溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么使用Pytorch構(gòu)建第一個神經(jīng)網(wǎng)絡(luò)模型

發(fā)布時間:2023-03-15 11:18:23 來源:億速云 閱讀:127 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“怎么使用Pytorch構(gòu)建第一個神經(jīng)網(wǎng)絡(luò)模型”,在日常操作中,相信很多人在怎么使用Pytorch構(gòu)建第一個神經(jīng)網(wǎng)絡(luò)模型問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么使用Pytorch構(gòu)建第一個神經(jīng)網(wǎng)絡(luò)模型”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

一、Pytorch簡介

PyTorch是一個基于python的科學計算包,主要針對兩類人群:

  • 作為NumPy的替代品,可以利用GPU的性能進行計算

  • 作為一個高靈活性、速度快的深度學習平臺

在PyTorch中搭建神經(jīng)網(wǎng)絡(luò)并使用真實的天氣信息預測明天是否會下雨。

  • 預處理 CSV 文件并將數(shù)據(jù)轉(zhuǎn)換為張量

  • 使用 PyTorch 構(gòu)建神經(jīng)網(wǎng)絡(luò)模型

  • 使用損失函數(shù)和優(yōu)化器來訓練模型

  • 評估模型并了解分類不平衡的危害

在開始構(gòu)建神經(jīng)網(wǎng)絡(luò)之前,首先了解一下幾個重要概念。

torch.Tensor
一個多維數(shù)組,支持諸如backward()等的自動求導操作,同時也保存了張量的梯度。

nn.Module
神經(jīng)網(wǎng)絡(luò)模塊。是一種方便封裝參數(shù)的方式,具有將參數(shù)移動到GPU、導出、加載等功能。

nn.Parameter
張量的一種,當它作為一個屬性分配給一個Module時,它會被自動注冊為一個參數(shù)。

autograd.Function
實現(xiàn)了自動求導前向和反向傳播的定義,每個Tensor至少創(chuàng)建一個Function節(jié)點,該節(jié)點連接到創(chuàng)建Tensor的函數(shù)并對其歷史進行編碼。

 二、實驗過程

2.1數(shù)據(jù)集介紹

數(shù)據(jù)集包含來自多個澳大利亞氣象站的每日天氣信息。本次目標是要回答一個簡單的問題:明天會下雨嗎?

2.2加載數(shù)據(jù)

首先導入本次實驗用到的第三方庫

import torch
 
import os
import numpy as np
import pandas as pd
from tqdm import tqdm
import seaborn as sns
from pylab import rcParams
import matplotlib.pyplot as plt
from matplotlib import rc
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix, classification_report
from torch import nn, optim
import torch.nn.functional as F
 
%matplotlib inline
%config InlineBackend.figure_format='retina'
 
sns.set(style='whitegrid', palette='muted', font_scale=1.2)
HAPPY_COLORS_PALETTE = ["#01BEFE", "#FFDD00", "#FF7D00", "#FF006D", "#93D30C", "#8F00FF"]
sns.set_palette(sns.color_palette(HAPPY_COLORS_PALETTE))
rcParams['figure.figsize'] = 12, 6
RANDOM_SEED = 42
np.random.seed(RANDOM_SEED)
torch.manual_seed(RANDOM_SEED)

接下來先通過Pandas讀取導入數(shù)據(jù)集

df = pd.read_csv('./data/weatherAUS.csv')
df.head()

怎么使用Pytorch構(gòu)建第一個神經(jīng)網(wǎng)絡(luò)模型

這里有很多特征列。也有很多NaN。下面來看看整體數(shù)據(jù)集大小。

df.shape

(145460, 23)

從數(shù)據(jù)集形狀看,這里數(shù)據(jù)還不少,超過14.5w條數(shù)據(jù)。

2.3數(shù)據(jù)預處理 

        在數(shù)據(jù)預處理這,我們并不希望數(shù)據(jù)集和目標問題有多復雜,嘗試將通過刪除大部分數(shù)據(jù)來簡化這個問題。這里只使用4個特征來預測明天是否會下雨。在你實際案例中,根據(jù)實際問題,特征數(shù)量可以比這多,也可以比這少,只要注意下面輸入數(shù)據(jù)維度即可。

cols = ['Rainfall', 'Humidity3pm', 'Pressure9am', 'RainToday', 'RainTomorrow']
df = df[cols]
2.3.1特征轉(zhuǎn)換

因為神經(jīng)網(wǎng)絡(luò)只能處理數(shù)字。所以我們將把文字的 yes 和 no 分別轉(zhuǎn)換為數(shù)字1 和 0。

df['RainToday'].replace({'No': 0, 'Yes': 1}, inplace = True)
df['RainTomorrow'].replace({'No': 0, 'Yes': 1}, inplace = True)
2.3.2缺失值處理

刪除缺少值的行。也許會有更好的方法來處理這些缺失的行,但我們這里將簡單地處理,直接刪除含有缺失值的行。

df = df.dropna(how='any')
df.head()

怎么使用Pytorch構(gòu)建第一個神經(jīng)網(wǎng)絡(luò)模型

 2.3.3樣本不平衡處理

到目前為止,我們有了一個可以使用的數(shù)據(jù)集。這里我們需要回答的一個重要問題是 -- 我們的數(shù)據(jù)集是否平衡? 或者 明天到底會下多少次雨?

因此通過sns.countplot函數(shù)直接定性分析整個樣本集中是否下雨分別多少次,以此判斷正負樣本(是否有雨)是否平衡。

sns.countplot(df.RainTomorrow);

怎么使用Pytorch構(gòu)建第一個神經(jīng)網(wǎng)絡(luò)模型

 從結(jié)果看,下雨次數(shù)明顯比不下雨次數(shù)要少很多。再通過具體定量計算正負樣本數(shù)。

df.RainTomorrow.value_counts() / df.shape[0]

0.0 0.778762
1.0 0.221238
Name: RainTomorrow, dtype: float64

事情看起來不妙。約78%的數(shù)據(jù)點表示明天不會下雨。這意味著一個預測明天是否下雨的模型在78%的時間里是正確的。

如果想要解決此次樣本不平衡可以采用欠采樣或過采樣處理,以緩解其帶來的影響,我們暫不做任何處理,但愿他對結(jié)果影響不大。

2.4特征工程

2.4.1劃分訓練集和測試集

數(shù)據(jù)預處理的最后一步是將數(shù)據(jù)分割為訓練集和測試集。這一步大家應該并不陌生,可以直接使用train_test_split()。

X = df[['Rainfall', 'Humidity3pm', 'RainToday', 'Pressure9am']]
y = df[['RainTomorrow']]
 
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=RANDOM_SEED)
2.4.2數(shù)據(jù)類型轉(zhuǎn)換

為了符合 PyTorch 所需求的數(shù)據(jù)類型。使用 python標準庫將數(shù)據(jù)加載到numpy數(shù)組里。然后將這個數(shù)組轉(zhuǎn)化成將全部數(shù)據(jù)轉(zhuǎn)換為張量(torch.Tensor)

注意:Torch張量和NumPy數(shù)組將共享它們的底層內(nèi)存位置,因此當一個改變時,另外也會改變。

X_train.head()

怎么使用Pytorch構(gòu)建第一個神經(jīng)網(wǎng)絡(luò)模型

 PyTorch中也是非常方便,直接通過from_numpy直接轉(zhuǎn)換。

X_train = torch.from_numpy(X_train.to_numpy()).float()
y_train = torch.squeeze(torch.from_numpy(y_train.to_numpy()).float())
 
X_test = torch.from_numpy(X_test.to_numpy()).float()
y_test = torch.squeeze(torch.from_numpy(y_test.to_numpy()).float())
 
print(X_train.shape, y_train.shape)
print(X_test.shape, y_test.shape)

torch.Size([99751, 4]) torch.Size([99751])
torch.Size([24938, 4]) torch.Size([24938])

到目前為止,所有數(shù)據(jù)準備工作已經(jīng)結(jié)束。

2.5構(gòu)建模型

        接下來我們將使用PyTorch建立一個簡單的神經(jīng)網(wǎng)絡(luò)(NN),嘗試預測明天是否會下雨。本次構(gòu)建的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)分為三個層,輸入層、輸出層和隱藏層。

輸入層: 我們的輸入包含四列數(shù)據(jù):"Rainfall, Humidity3pm, RainToday, Pressure9am"(降雨量,濕度下午3點,今天下雨,壓力上午9點)。將為此創(chuàng)建一個適當?shù)妮斎雽印?/p>

輸出層: 輸出將是一個介于 0 和 1 之間的數(shù)字,代表模型認為明天下雨的可能性。預測將由網(wǎng)絡(luò)的輸出層提供給我們。

隱藏層: 將在輸入層和輸出層之間添加兩個隱藏層。這些層的參數(shù)(神經(jīng)元)將決定最終輸出。所有層都將是全連接的,即全連接層。

一個神經(jīng)網(wǎng)絡(luò)的典型訓練過程如下:

  • 定義包含一些可學習參數(shù)(或者叫權(quán)重)的神經(jīng)網(wǎng)絡(luò)

  • 在輸入數(shù)據(jù)集上迭代

  • 通過網(wǎng)絡(luò)處理輸入

  • 計算loss(輸出和正確答案的距離)

  • 將梯度反向傳播給網(wǎng)絡(luò)的參數(shù)

  • 更新網(wǎng)絡(luò)的權(quán)重,一般使用一個簡單的規(guī)則:weight = weight - learning_rate * gradient

        可以使用torch.nn包來構(gòu)建神經(jīng)網(wǎng)絡(luò)。即使用 PyTorch 構(gòu)建神經(jīng)網(wǎng)絡(luò)的一種簡單方法是創(chuàng)建一個繼承自 torch.nn.Module 的類。

        這里將nn.Module子類化(它本身是一個類并且能夠跟蹤狀態(tài))。在這種情況下,我們要創(chuàng)建一個類,該類包含前進步驟的權(quán)重,偏差和方法。nn.Module具有許多我們將要使用的屬性和方法(例如.parameters()和.zero_grad())。

class Net(nn.Module):
 
    def __init__(self, n_features):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(n_features, 5)
        self.fc2 = nn.Linear(5, 3)
        self.fc3 = nn.Linear(3, 1)
 
    def forward(self, x):
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        return torch.sigmoid(self.fc3(x))

 我們只需要定義 forward 函數(shù),backward函數(shù)會在使用autograd時自動定義,backward函數(shù)用來計算導數(shù)。我們可以在 forward 函數(shù)中使用任何針對張量的操作和計算。

2.5.1可視化神經(jīng)元
net = Net(X_train.shape[1])
# pip install graphviz
# mac上安裝graphviz 需要用 brew install graphviz 
ann_viz(net, view=True)

怎么使用Pytorch構(gòu)建第一個神經(jīng)網(wǎng)絡(luò)模型

我們首先在構(gòu)造函數(shù)中創(chuàng)建模型的層。forward()方法是奇跡發(fā)生的地方。它接受輸入  并允許它流過每一層。有一個相應的由PyTorch定義到向后傳遞backward()方法,它允許模型從當前發(fā)生的誤差中學習,并修正模型參數(shù)。

2.5.2激活函數(shù)

        細心的小伙伴可能會注意到構(gòu)建的神經(jīng)網(wǎng)絡(luò)中調(diào)用 F.relu 和 torch.sigmoid 。這些是激活函數(shù),那我們?yōu)槭裁葱枰@些?

        神經(jīng)網(wǎng)絡(luò)的一個很酷的特性是它們可以近似非線性函數(shù)。事實上,已經(jīng)證明它們可以逼近任何函數(shù)。不過,如果想通過堆疊線性層來逼近非線性函數(shù),此時就需要激活函數(shù)。激活函數(shù)可以讓神經(jīng)網(wǎng)絡(luò)擺脫線性世界并學習更多。通常將其應用于某個層的輸出。

ReLU

從最廣泛使用的激活函數(shù)之一的 ReLU 定義開始:

怎么使用Pytorch構(gòu)建第一個神經(jīng)網(wǎng)絡(luò)模型

 該激活函數(shù)簡單易行,其結(jié)果就是輸入值與零比較,得到的最大值。

從可視化結(jié)果看

ax = plt.gca()
plt.plot(
  np.linspace(-1, 1, 5), 
  F.relu(torch.linspace(-1, 1, steps=5)).numpy()
)
ax.set_ylim([-1.5, 1.5]);

怎么使用Pytorch構(gòu)建第一個神經(jīng)網(wǎng)絡(luò)模型

 Sigmoid

它被定義為:

怎么使用Pytorch構(gòu)建第一個神經(jīng)網(wǎng)絡(luò)模型

 當需要進行二元決策 / 分類(回答yes或no)時,sigmoid 函數(shù)是很有用的。sigmoid 以一種超級的方式將輸入值壓縮在 0 和 1 之間。

從可視化結(jié)果看

ax = plt.gca()
 
plt.plot(
  np.linspace(-10, 10, 100), 
  torch.sigmoid(torch.linspace(-10, 10, steps=100)).numpy()
)
ax.set_ylim([-0.5, 1.5]);

怎么使用Pytorch構(gòu)建第一個神經(jīng)網(wǎng)絡(luò)模型

2.5.3訓練神經(jīng)網(wǎng)絡(luò) 

        目前為止,我們已經(jīng)看到了如何定義網(wǎng)絡(luò),接下來需要找到預測明天是否會下雨的參數(shù)。即需要找到該模型應用于此次問題的最佳參數(shù)。而要想做到這點,首先需要一些評價指標來告訴我們,該模型目前做得有多好。接下來需要計算損失,并更新網(wǎng)絡(luò)的權(quán)重。

損失函數(shù)

一個損失函數(shù)接受一對(output, target)作為輸入,計算一個值來估計網(wǎng)絡(luò)的輸出和目標值相差多少。BCELoss是一個損失函數(shù),其度量兩個向量之間的差。

criterion = nn.BCELoss()

而在我們的例子中,這兩個向量即是我們的模型的預測和實際值。該損失函數(shù)的期望值由 sigmoid 函數(shù)輸出。該值越接近 0,模型效果越好。

但是我們?nèi)绾握业阶钚』瘬p失函數(shù)的參數(shù)呢?

優(yōu)化器

        假設(shè)我們的神經(jīng)網(wǎng)絡(luò)的每個參數(shù)都是一個旋鈕。優(yōu)化器的工作是為每個旋鈕找到完美的位置,使損失接近0。實戰(zhàn)中,模型可能包含數(shù)百萬甚至數(shù)十億個參數(shù)。有這么多旋鈕要轉(zhuǎn),如果有一個高效的優(yōu)化器可以快速找到解決方案,那就完美了。而理想很豐滿,現(xiàn)實很骨感。深度學習中的優(yōu)化效果只能達到令人滿意的結(jié)果。在實踐中,可以提供可接受的準確性的足夠好的參數(shù),就應該心滿意足了。在使用神經(jīng)網(wǎng)絡(luò)時,PyTorch中提供了許多經(jīng)過良好調(diào)試過的優(yōu)化器,可能希望使用各種不同的更新規(guī)則,如SGD、Nesterov-SGD、Adam、RMSProp等。雖然你可以從這些優(yōu)化器中選擇,一般情況下,首選的還是Adam。

optimizer = optim.Adam(net.parameters(), lr=0.001)

一個模型的可學習參數(shù)可以通過net.parameters()。

        自然地,優(yōu)化器需要輸入?yún)?shù)。第二個參數(shù)lr 是 learning rate (學習率),這是要找到的最優(yōu)參數(shù)和到達最優(yōu)解的速度之間的權(quán)衡。而為此找到最優(yōu)解的方法或過程可能是黑魔法和大量的暴力“實驗”。

在 GPU 上計算

        在 GPU 上進行大規(guī)模并行計算是現(xiàn)代深度學習的推動因素之一。為此,您將需要配置 NVIDIA GPU。如果你的設(shè)備上裝有GPU,PyTorch 中可以非常輕松地將所有計算傳輸?shù)?GPU。

       我們首先檢查 CUDA 設(shè)備是否可用。然后,我們將所有訓練和測試數(shù)據(jù)傳輸?shù)皆撛O(shè)備。最后移動模型和損失函數(shù)。張量可以使用.to方法移動到任何設(shè)備(device)上。

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
 
X_train = X_train.to(device)
y_train = y_train.to(device)
 
X_test = X_test.to(device)
y_test = y_test.to(device)
 
net = net.to(device)
criterion = criterion.to(device)

尋找最優(yōu)參數(shù)

        擁有損失函數(shù)固然很好,追蹤模型的準確性是一件更容易理解的事情,而一般通過定義準確性來做模型評價。

def calculate_accuracy(y_true, y_pred):
    predicted = y_pred.ge(.5).view(-1)
    return (y_true == predicted).sum().float() / len(y_true)

        我們定義一個預值,將連續(xù)概率值轉(zhuǎn)換為二分類值。即將每個低于 0.5 的值轉(zhuǎn)換為 0,高于0.5的值設(shè)置為 1。最后計算正確值的百分比。所有的模塊都準備好了,我們可以開始訓練我們的模型了。

def round_tensor(t, decimal_places=3):
    return round(t.item(), decimal_places)
 
for epoch in range(1000):    
    y_pred = net(X_train)
    y_pred = torch.squeeze(y_pred)
    train_loss = criterion(y_pred, y_train)
    
    if epoch % 100 == 0:
        train_acc = calculate_accuracy(y_train, y_pred)
 
        y_test_pred = net(X_test)
        y_test_pred = torch.squeeze(y_test_pred)
 
        test_loss = criterion(y_test_pred, y_test)
        test_acc = calculate_accuracy(y_test, y_test_pred)
        print(f'''epoch {epoch}
              Train set - loss: {round_tensor(train_loss)}, accuracy: {round_tensor(train_acc)}
              Test  set - loss: {round_tensor(test_loss)}, accuracy: {round_tensor(test_acc)}
              ''')
    
    optimizer.zero_grad()  # 清零梯度緩存
    train_loss.backward() # 反向傳播誤差
    optimizer.step()  # 更新參數(shù)
def round_tensor(t, decimal_places=3):
    return round(t.item(), decimal_places)
 
for epoch in range(1000):    
    y_pred = net(X_train)
    y_pred = torch.squeeze(y_pred)
    train_loss = criterion(y_pred, y_train)
    
    if epoch % 100 == 0:
        train_acc = calculate_accuracy(y_train, y_pred)
 
        y_test_pred = net(X_test)
        y_test_pred = torch.squeeze(y_test_pred)
 
        test_loss = criterion(y_test_pred, y_test)
        test_acc = calculate_accuracy(y_test, y_test_pred)
        print(f'''epoch {epoch}
              Train set - loss: {round_tensor(train_loss)}, accuracy: {round_tensor(train_acc)}
              Test  set - loss: {round_tensor(test_loss)}, accuracy: {round_tensor(test_acc)}
              ''')
    
    optimizer.zero_grad()  # 清零梯度緩存
    train_loss.backward() # 反向傳播誤差
    optimizer.step()  # 更新參數(shù)

怎么使用Pytorch構(gòu)建第一個神經(jīng)網(wǎng)絡(luò)模型

        在訓練期間,我們向模型傳輸數(shù)據(jù)共計10,000次。每次測量損失時,將誤差傳播到模型中,并要求優(yōu)化器找到更好的參數(shù)。用 zero_grad() 方法清零所有參數(shù)的梯度緩存,然后進行隨機梯度的反向傳播。如果忽略了這一步,梯度將會累積,導致模型不可用。測試集上的準確率為 83.4% 聽起來挺合理,但可能要讓你失望了,這樣的結(jié)果并不是很理想,接下來看看是如何不合理。但首先我們需要學習如何保存和加載訓練好的模型。

2.6保存模型

        訓練一個好的模型可能需要很多時間??赡苁菐字?、幾個月甚至幾年。如果在訓練過程了忘記保存,或不知道需要保存模型,這將會是非常痛苦的事情。因此這里需要確保我們知道如何保存寶貴的工作。其實保存很容易,但你不能忘記這件事。

MODEL_PATH = 'model.pth'  # 后綴名為 .pth
torch.save(net, MODEL_PATH) # 直接使用torch.save()函數(shù)即可

當然恢復模型也很容易,直接使用 torch.load() 函數(shù)即可。

net = torch.load(MODEL_PATH)

2.7模型評估

        如果知道你的模型會犯什么樣的錯誤不是很好嗎?當然,這一點是非常難做到的。但是你可以通過一定的方法得到一個估計值。而僅使用準確性來評估并不是一個好方法,尤其在樣本不平衡的二分類數(shù)據(jù)集上。仔細回想一下,我們的數(shù)據(jù)是一個很不平衡的數(shù)據(jù)集,其幾乎不包含明天會降雨樣本。深入研究模型性能的一種方法是評估每個類的精確度和召回率。在我們的例子中,將是結(jié)果標簽分別是 no rain 和 rain 。        

classes = ['No rain', 'Raining']
 
y_pred = net(X_test)
y_pred = y_pred.ge(.5).view(-1).cpu()
y_test = y_test.cpu()
 
print(classification_report(y_test, y_pred, target_names=classes))

怎么使用Pytorch構(gòu)建第一個神經(jīng)網(wǎng)絡(luò)模型

精確度最大值為1,表明該模型只適用于識別相關(guān)的樣本。召回率最大值為1,表示模型可以在這個類的數(shù)據(jù)集中找到所有相關(guān)的示例??梢钥吹侥P驮跓o雨類方面表現(xiàn)良好,因為樣本中無雨類樣本數(shù)量較大。不幸的是,我們不能完全相信有雨類的預測,因為樣本不平衡導致模型傾向于無雨類。可以通過查看一個簡單的混淆矩陣來評估二分類效果。

cm = confusion_matrix(y_test, y_pred)
df_cm = pd.DataFrame(cm, index=classes, columns=classes)
 
hmap = sns.heatmap(df_cm, annot=True, fmt="d")
hmap.yaxis.set_ticklabels(hmap.yaxis.get_ticklabels(), rotation=0, ha='right')
hmap.xaxis.set_ticklabels(hmap.xaxis.get_ticklabels(), rotation=30, ha='right')
plt.ylabel('True label')
plt.xlabel('Predicted label');

怎么使用Pytorch構(gòu)建第一個神經(jīng)網(wǎng)絡(luò)模型

 你可以清楚地看到,當我們的模型預測要下雨時,我們應該抱有懷疑的態(tài)度。

2.8模型預測

使用一些假設(shè)的例子上測試下模型。

def will_it_rain(rainfall, humidity, rain_today, pressure):
    t = torch.as_tensor([rainfall, humidity, rain_today, pressure]) \
      .float() \
      .to(device)
    output = net(t)
    return output.ge(0.5).item()

這個函數(shù)將根據(jù)模型預測返回一個布爾值。讓我們試試看:

will_it_rain(rainfall=10, humidity=10, 
             rain_today=True, pressure=2)
>>> True
will_it_rain(rainfall=0, humidity=1, 
             rain_today=False, pressure=100)
>>> False

        根據(jù)一些參數(shù)得到了兩種不同的返回值。到這里為止,模型已準備好部署來,但實際情況下,請不要匆忙部署,因為該模型并不是一個最佳的狀態(tài),只是用來掩飾如何使用PyTorch搭建模型!

到此,關(guān)于“怎么使用Pytorch構(gòu)建第一個神經(jīng)網(wǎng)絡(luò)模型”的學習就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI