1. 程式人生 > 實用技巧 >Keras vs PyTorch vs Caffe:CNN實現對比

Keras vs PyTorch vs Caffe:CNN實現對比

作者|PRUDHVI VARMA
編譯|VK
來源|Analytics Indiamag

在當今世界,人工智慧已被大多數商業運作所應用,而且由於先進的深度學習框架,它非常容易部署。這些深度學習框架提供了高階程式設計介面,幫助我們設計深度學習模型。使用深度學習框架,它通過提供內建的庫函式來減少開發人員的工作,從而使我們能夠更快更容易地構建模型。

在本文中,我們將構建相同的深度學習框架,即在Keras、PyTorch和Caffe中對同一資料集進行卷積神經網路影象分類,並對所有這些方法的實現進行比較。最後,我們將看到PyTorch構建的CNN模型如何優於內建Keras和Caffe的同行。

本文涉及的主題

  • 如何選擇深度學習框架。

  • Keras的優缺點

  • PyTorch的優缺點

  • Caffe的優缺點

  • 在Keras、PyTorch和Caffe實現CNN模型。

選擇深度學習框架

在選擇深度學習框架時,有一些指標可以找到最好的框架,它應該提供平行計算、良好的執行模型的介面、大量內建的包,它應該優化效能,同時也要考慮我們的業務問題和靈活性,這些是我們在選擇深度學習框架之前要考慮的基本問題。讓我們比較三個最常用的深度學習框架Keras、Pytorch和Caffe。

Keras

Keras是一個開源框架,由Google工程師Francois Chollet開發,它是一個深度學習框架,我們只需編寫幾行程式碼,就可以輕鬆地使用和評估我們的模型。

如果你不熟悉深度學習,Keras是初學者最好的入門框架,Keras對初學者十分友好,並且易於與python一起工作,並且它有許多預訓練模型(VGG、Inception等)。不僅易於學習,而且它支援Tensorflow作為後端。

使用Keras的侷限性

  • Keras需要改進一些特性

  • 我們需要犧牲速度來換取它的使用者友好性

  • 有時甚至使用gpu也需要很長時間。

使用Keras框架的實際實現

在下面的程式碼片段中,我們將匯入所需的庫。

import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras import backend as K

超引數:

batch_size = 128
num_classes = 10
epochs = 12
img_rows, img_cols = 28, 28
(x_train, y_train), (x_test, y_test) = mnist.load_data()

在下面的程式碼片段中,我們將構建一個深度學習模型,其中包含幾個層,並分配優化器、啟用函式和損失函式。

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),
                 activation='relu',
                 input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.Adam(),
              metrics=['accuracy'])

在下面的程式碼片段中,我們將訓練和評估模型。

model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          verbose=1,
          validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

PyTorch

PyTorch是一個由Facebook研究團隊開發的開源框架,它是深度學習模型的一種實現,它提供了python環境提供的所有服務和功能,它允許自動微分,有助於加速反向傳播過程,PyTorch提供了各種模組,如torchvision,torchaudio,torchtext,可以靈活地在NLP中工作,計算機視覺。PyTorch對於研究人員比開發人員更靈活。

PyTorch的侷限性

  • PyTorch在研究人員中比在開發人員中更受歡迎。

  • 它缺乏生產力。

使用PyTorch框架實現

安裝所需的庫

import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.utils.data.dataloader as dataloader
import torch.optim as optim
from torch.utils.data import TensorDataset
from torchvision import transforms
from torchvision.datasets import MNIST

在下面的程式碼片段中,我們將載入資料集並將其拆分為訓練集和測試集。

train = MNIST('./data', train=True, download=True, transform=transforms.Compose([
    transforms.ToTensor(), 
]), )
test = MNIST('./data', train=False, download=True, transform=transforms.Compose([
    transforms.ToTensor(),
]), )
dataloader_args = dict(shuffle=True, batch_size=64,num_workers=1, pin_memory=True)
train_loader = dataloader.DataLoader(train, **dataloader_args)
test_loader = dataloader.DataLoader(test, **dataloader_args)
train_data = train.train_data
train_data = train.transform(train_data.numpy())

在下面的程式碼片段中,我們將構建我們的模型,並設定啟用函式和優化器。

class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.fc1 = nn.Linear(784, 548)
        self.bc1 = nn.BatchNorm1d(548) 
        self.fc2 = nn.Linear(548, 252)
        self.bc2 = nn.BatchNorm1d(252)
        self.fc3 = nn.Linear(252, 10)              
    def forward(self, x):
        a = x.view((-1, 784))
        b = self.fc1(a)
        b = self.bc1(b)
        b = F.relu(b)
        b = F.dropout(b, p=0.5) 
        b = self.fc2(b)
        b = self.bc2(b)
        b = F.relu(b)
        b = F.dropout(b, p=0.2)
        b = self.fc3(b)
        out = F.log_softmax(b)
        return out
model = Model()
model.cuda()
optimizer = optim.SGD(model.parameters(), lr=0.001)

在下面的程式碼片段中,我們將訓練我們的模型,在訓練時,我們將指定損失函式,即交叉熵。

model.train()
losses = []
for epoch in range(12):
    for batch_idx, (data,data_1) in enumerate(train_loader):
        data,data_1 = Variable(data.cuda()), Variable(target.cuda())
        optimizer.zero_grad()
        y_pred = model(data) 
        loss = F.cross_entropy(y_pred, target)
        losses.append(loss.data[0])
        loss.backward()
        optimizer.step()
        if batch_idx % 100 == 1:
            print('\r Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, 
                batch_idx * len(data), 
                len(train_loader.dataset), 100. * batch_idx / len(train_loader),
                                loss.data[0]), 
                end='')         
    print()

#評估模型

evaluate=Variable(test_loader.dataset.test_data.type_as(torch.FloatTensor())).cuda()
output = model(evaluate)
predict = output.data.max(1)[1]
pred = pred.eq(evaluate.data)
accuracy = pred.sum()/pred.size()[0]
print('Accuracy:', accuracy)

Caffe

Caffe(Convolutional Architecture for Fast Feature Embedding)是Yangqing Jia開發的開源深度學習框架。該框架支援人工智慧領域的研究人員和工業應用。

大部分開發者使用Caffe是因為它的速度,它使用一個NVIDIA K40 GPU每天可以處理6000萬張影象。Caffe有很多貢獻者來更新和維護框架,而且與深度學習的其他領域相比,Caffe在計算機視覺模型方面工作得很好。

Caffe的侷限性

Caffe沒有更高級別的API,所以很難做實驗。

在Caffe中,為了部署我們的模型,我們需要編譯原始碼。

安裝Caffe

!apt install -y caffe-tools-cpu

匯入所需的庫

import os
import numpy as np
import math
import caffe
import lmdb

在下面的程式碼片段中,我們將指定硬體環境。

os.environ["GLOG_minloglevel"] = '2'
CAFFE_ROOT="/caffe"
os.chdir(CAFFE_ROOT) 
USE_GPU = True
if USE_GPU:
    caffe.set_device(0)
    caffe.set_mode_gpu()
else:
    caffe.set_mode_cpu()
caffe.set_random_seed(1) 
np.random.seed(24)

在下面的程式碼片段中,我們將定義有助於資料轉換的image_generator和batch_generator 。

def image_generator(db_path):
    db_handle = lmdb.open(db_path, readonly=True) 
    with db_handle.begin() as db:
        cur = db.cursor() 
        for _, value in cur: 
            datum = caffe.proto.caffe_pb2.Datum()
            datum.ParseFromString(value) 
            int_x = caffe.io.datum_to_array(datum) 
            x = np.asfarray(int_x, dtype=np.float32) t
            yield x - 128 

def batch_generator(shape, db_path):
    gen = image_generator(db_path)
    res = np.zeros(shape) 
    while True: 
        for i in range(shape[0]):
            res[i] = next(gen) 

        yield res

在下面的程式碼片段中,我們將給出MNIST資料集的路徑。

num_epochs = 0 
iter_num = 0 
db_path = "content/mnist/mnist_train_lmdb"
db_path_test = "content/mnist/mnist_test_lmdb"
base_lr = 0.01
gamma = 1e-4
power = 0.75

for epoch in range(num_epochs):
    print("Starting epoch {}".format(epoch))
    input_shape = net.blobs["data"].data.shape
    for batch in batch_generator(input_shape, db_path):
        iter_num += 1
        net.blobs["data"].data[...] = batch
        net.forward()
        for name, l in zip(net._layer_names, net.layers):
            for b in l.blobs:
                b.diff[...] = net.blob_loss_weights[name]
        net.backward()
        learning_rate = base_lr * math.pow(1 + gamma * iter_num, - power)
        for l in net.layers:
            for b in l.blobs:
                b.data[...] -= learning_rate * b.diff
        if iter_num % 50 == 0:
            print("Iter {}: loss={}".format(iter_num, net.blobs["loss"].data))
        if iter_num % 200 == 0:
            print("Testing network: accuracy={}, loss={}".format(*test_network(test_net, db_path_test)))

使用下面的程式碼片段,我們將獲得最終的準確性。

print("Training finished after {} iterations".format(iter_num))
print("Final performance: accuracy={}, loss={}".format(*test_network(test_net, db_path_test)))

結論

在本文中,我們演示了使用三個著名框架:Keras、PyTorch和Caffe實現CNN影象分類模型的。我們可以看到,PyTorch開發的CNN模型在精確度和速度方面都優於在Keras和Caffe開發的CNN模型。

作為一個初學者,我一開始使用Keras,這對於初學者是一個非常簡單的框架,但它的應用是有限的。但是PyTorch和Caffe在速度、優化和平行計算方面是非常強大的框架。

原文連結:https://analyticsindiamag.com/keras-vs-pytorch-vs-caffe-comparing-the-implementation-of-cnn/

歡迎關注磐創AI部落格站:
http://panchuang.net/

sklearn機器學習中文官方文件:
http://sklearn123.com/

歡迎關注磐創部落格資源彙總站:
http://docs.panchuang.net/