首頁>科技>

背景

很多同學想學習深度學習,但是無奈自己的機器老舊,要麼顯示卡老舊,要麼不是Nvidia的顯示卡,有的甚至沒有顯示卡。沒有GPU加速,深度學習還怎麼玩?乖乖,怎麼能夠抵擋我成為一名學霸呢。

學霸 vs 學渣

辦法總比困難多,來薅一下資本主義羊毛吧,那就是google的Colab notebooks。jupyter notebook想必大家不陌生,如果你不知道的話,還搞啥深度學習!!!而這個Colab notebooks就原生支援它。這個很久就知道了,一直也沒時間去整理,現在整理一下。話說,Colab notebooks的效果比以往好很多。

前提:這時需要能夠開啟google哦,否則就不用看了。

1 瞭解Colab notebooks1.1 建立notebooks

首先,進入Google雲端網盤[1],如下圖:

雲端網盤

建立notebook

設定遠端執行程式,如下圖:

設定遠端執行程式

設定程式執行環境,預設是使用cpu執行的,

設定程式執行環境

可選裝置如下:

裝置選擇

看,除了GPU外,還有TPU。貧窮的我,還不知道TPU是如何使用的。

1.2 基本指令瞭解

如果你懂一些linux指令那就更好了。首先,我們看看python的版本。

檢視python版本

在notebooks中使用英文的感嘆號加上linux命令,就可以執行linux命令了。從上面可以看出python版本是3.6。

檢視一下是否有numpy包,如下:

檢視python包

同理看看環境中是否安裝了其他包,例如:pytorch_lightning這個包就沒有安裝。

檢視python包

那麼,我們就來按照這個包,如下:

安裝python包

看看當前程式執行的路徑吧,因為可能要載入資料,那麼就需要用到路徑,如下:

程式路徑

當然,你還是不知道這個路徑在哪。其實你可以理解這就是和linux中與\opt,\home等目錄統計的目錄。帶你看看,按下面操作:

檢視目錄結構

那麼就會有:

目錄結構

系統目錄

瞭解linux系統目錄的同學是不是豁然開朗了呀。下面要操作的就是把我們google driver掛載過來,也就是把一個磁碟加進來,操作如下:

掛在網盤

檢視當前notebook檔案所處路徑如下:

當前notebook檔案路徑

下面就可以愉快地使用自己的訓練資料咯。上傳檔案就相當簡單了,先看一下網盤目錄:

網盤目錄

那麼就資料拖上去就行了。

既然這個平臺支援GPU加速,我們看看到底是什麼GPU。如下:

檢視gpu資訊

可以看出GPU是Tesla T4。對我們苦逼一族,咋知道Tesla系列的GPU效果如何呀!我查閱了其計算效能和2080Ti是一樣的(別高興太早哦),如圖:

T4

2080Ti

查閱網址:https://developer.nvidia.com/zh-cn/cuda-gpus 。那麼到底加速如何,我們跑一個深度學習demo就知道了。

2 執行一個demo

如何構建一個notebooks已經知曉了,現在來執行一個深度學習demo吧。這個demo是之前使用textcnn進行文字分類的案例【深度學習】textCNN論文與原理——短文字分類(基於pytorch和torchtext)[2]。程式碼和語料已經放在如下路徑了:

程式碼

為了減少你在原來專案的基礎上修改程式碼,修改後程式碼就粘過來了:

import torchimport matplotlib.pyplot as pltfrom torch import nn, optimfrom torchtext import dataimport randomfrom torch import nnimport osimport numpy as npimport timeif os.getcwd() != '/content/drive/My Drive/Colab Notebooks':  os.chdir('/content/drive/MyDrive/Colab Notebooks')device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# device = torch.device("cpu")# 文字內容,使用自定義的分詞方法,將內容轉換為小寫,設定最大長度等TEXT = data.Field(tokenize=lambda x:x.split(), lower=True, fix_length=50, batch_first=True)# 文字對應的標籤LABEL = data.LabelField(dtype=torch.float)def get_dataset(corpus_path, text_field, label_field, datatype):    """    構建torchtext資料集    :param corpus_path: 資料路徑    :param text_field: torchtext設定的文字域    :param label_field: torchtext設定的文字標籤域    :param datatype: 文字的類別    :return: torchtext格式的資料集以及設定的域    """    fields = [('text', text_field), ('label', label_field)]    examples = []    with open(corpus_path, encoding='utf8') as reader:        for line in reader:            content = line.rstrip()            if datatype == 'pos':                label = 1            else:                label = 0            # content[:-2]是由於原始文字最後的兩個內容是空格和.,這裡直接去掉,並將資料與設定的域對應起來            examples.append(data.Example.fromlist([content[:-2], label], fields))    return examples, fields# 構建data資料pos_examples, pos_fields = get_dataset('./corpus/pos.txt', TEXT, LABEL, 'pos')neg_examples, neg_fields = get_dataset('./corpus/neg.txt', TEXT, LABEL, 'neg')all_examples, all_fields = pos_examples + neg_examples, pos_fields + neg_fields# 構建torchtext型別的資料集total_data = data.Dataset(all_examples, all_fields)# 資料集切分train_data, test_data = total_data.split(random_state=random.seed(1000), split_ratio=0.8)# 為該樣本資料構建字典,並將子每個單詞對映到對應數字TEXT.build_vocab(train_data)LABEL.build_vocab(train_data).# 構建迭代(iterator)型別的資料train_iterator, test_iterator = data.BucketIterator.splits((train_data, test_data),batch_size=128,sort=False)class TextCNN(nn.Module):    # output_size為輸出類別(2個類別,0和1),三種kernel,size分別是3,4,5,每種kernel有100個    def __init__(self, vocab_size, embedding_dim, output_size, filter_num=100, kernel_list=(3, 4, 5), dropout=0.5):        super(TextCNN, self).__init__()        self.embedding = nn.Embedding(vocab_size, embedding_dim)        # 1表示channel_num,filter_num即輸出資料通道數,卷積核大小為(kernel, embedding_dim)        self.convs = nn.ModuleList([            nn.Sequential(nn.Conv2d(1, filter_num, (kernel, embedding_dim)),                          nn.LeakyReLU(),                          nn.MaxPool2d((50 - kernel + 1, 1)))            for kernel in kernel_list        ])        self.fc = nn.Linear(filter_num * len(kernel_list), output_size)        self.dropout = nn.Dropout(dropout)    def forward(self, x):        x = self.embedding(x)  # [128, 50, 200] (batch, seq_len, embedding_dim)        x = x.unsqueeze(1)  # [128, 1, 50, 200] 即(batch, channel_num, seq_len, embedding_dim)        out = [conv(x) for conv in self.convs]        out = torch.cat(out, dim=1)  # [128, 300, 1, 1],各通道的資料拼接在一起        out = out.view(x.size(0), -1)  # 展平        out = self.dropout(out)  # 構建dropout層        logits = self.fc(out)  # 結果輸出[128, 2]        return logits# 建立模型text_cnn =TextCNN(len(TEXT.vocab), 128, len(LABEL.vocab)).to(device)print('device:', device)# 選取最佳化器optimizer = optim.Adam(text_cnn.parameters(), lr=1e-3)# 選取損失函式criterion = nn.CrossEntropyLoss()# 繪製結果model_train_acc, model_test_acc = [], []def binary_acc(pred, y):    """    計算模型的準確率    :param pred: 預測值    :param y: 實際真實值    :return: 返回準確率    """    correct = torch.eq(pred, y).float()    acc = correct.sum() / len(correct)    return accdef train(model, train_data, optimizer, criterion):    """    模型訓練    :param model: 訓練的模型    :param train_data: 訓練資料    :param optimizer: 最佳化器    :param criterion: 損失函式    :return: 該論訓練各批次正確率平均值    """    avg_acc = []    model.train()       # 進入訓練模式    for i, batch in enumerate(train_data):        pred = model(batch.text.to(device)).cpu()        loss = criterion(pred, batch.label.long())        acc = binary_acc(torch.max(pred, dim=1)[1], batch.label)        avg_acc.append(acc)        optimizer.zero_grad()        loss.backward()        optimizer.step()    # 計算所有批次資料的結果    avg_acc = np.array(avg_acc).mean()    return avg_accdef evaluate(model, test_data):    """    使用測試資料評估模型    :param model: 模型    :param test_data: 測試資料    :return: 該論訓練好的模型預測測試資料,檢視預測情況    """    avg_acc = []    model.eval()  # 進入測試模式    with torch.no_grad():        for i, batch in enumerate(test_data):            pred = model(batch.text.to(device)).cpu()            acc = binary_acc(torch.max(pred, dim=1)[1], batch.label)            avg_acc.append(acc)    return np.array(avg_acc).mean()# 模型訓練start = time.time()for epoch in range(10):    train_acc = train(text_cnn, train_iterator, optimizer, criterion)    print("epoch = {}, 訓練準確率={}".format(epoch + 1, train_acc))    test_acc = evaluate(text_cnn, test_iterator)    print("epoch = {}, 測試準確率={}".format(epoch + 1, test_acc))    model_train_acc.append(train_acc)    model_test_acc.append(test_acc)print('total train time:', time.time() - start)# 繪製訓練過程plt.plot(model_train_acc)plt.plot(model_test_acc)plt.ylim(ymin=0.5, ymax=1.01)plt.title("The accuracy of textCNN model")plt.legend(['train', 'dev test'])plt.show()

使用GPU執行時間如下:

程式執行

不使用GPU執行如下:

CPU執行

確實使用GPU會快一點,但是我本機使用GTX 950M執行時間如下:

本地執行

反而更快,還是快了不少,但是比本地CPU去跑還是快了不少。資本主義羊毛不好薅呀。

參考資料

[1] Google雲端網盤: https://drive.google.com/drive/my-drive

[2] 【深度學習】textCNN論文與原理——短文字分類(基於pytorch和torchtext): https://piqiandong.blog.csdn.net/article/details/111824774

11
  • 整治雙十一購物亂象,國家再次出手!該跟這些套路說再見了
  • 低功耗廣域網(LPWAN)技術 - mioty簡介