深ハンズオン科学学習 - 畳み込みニューラルネットワーク2 LeNet

ここに画像を挿入説明
ホワイトボーゆうプラットフォームを娼婦、または波の広告を再生し、およそ感謝します。
主に研究ノートは、問題解決には時間と労力を無駄にしないように、このブログでは無視することができ
三つの領域に焦点を当てて

記載lenetモデル
lenetネットワーク構造が
画像認識を使用lenetセット-fashion-mnist

LeNetモデル

LeNet層ブロック畳み込み二つの部分と完全に接続層ブロック。我々の下にはこれら二つのモジュールについて説明します。
以下のモデル構造の
ここに画像を挿入説明
前記入力層、二層の畳み込みは、2つの隠し層が完全に接続され、出力層は、完全に接続されました

基本単位電池層の平均アクセス層畳み込みにおけるレイヤブロック畳み込み:畳み込み層は、線およびローカルオブジェクトのような空間パターンで画像を識別するのに役立つ、層後の平均細胞層は畳み込みを低減するために使用されます位置の感度。

二つのそのような基本単位の階層ブロックコンボリューションを繰り返し設定を積層されています。レイヤブロック畳み込みは、それぞれの層における畳み込みは、5×5ウィンドウを使用し、出力にシ​​グモイド活性化関数を使用して。最初の畳み込み層出力チャネルは、第二の畳み込み層16への出力チャンネルの数を増加させ、6です。

完全に接続されたレイヤブロックが完全に接続3層を含みます。10は、出力クラスの数が出力数、そのそれぞれ120,84及び10、。

今、私たちは、シーケンシャルクラスによってLeNetモデルを実現するために来ます。

#import
import sys
sys.path.append("/home/kesci/input")
import d2lzh1981 as d2l
import torch
import torch.nn as nn
import torch.optim as optim
import time
#net
class Flatten(torch.nn.Module):  #展平操作
    def forward(self, x):
        return x.view(x.shape[0], -1)

class Reshape(torch.nn.Module): #将图像大小重定型
    def forward(self, x):
        return x.view(-1,1,28,28)      #(B x C x H x W)
    
net = torch.nn.Sequential(     #Lelet                                                  
    Reshape(),
    nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5, padding=2), #b*1*28*28  =>b*6*28*28
    nn.Sigmoid(),                                                       
    nn.AvgPool2d(kernel_size=2, stride=2),                              #b*6*28*28  =>b*6*14*14
    nn.Conv2d(in_channels=6, out_channels=16, kernel_size=5),           #b*6*14*14  =>b*16*10*10
    nn.Sigmoid(),
    nn.AvgPool2d(kernel_size=2, stride=2),                              #b*16*10*10  => b*16*5*5
    Flatten(),                                                          #b*16*5*5   => b*400
    nn.Linear(in_features=16*5*5, out_features=120),
    nn.Sigmoid(),
    nn.Linear(120, 84),
    nn.Sigmoid(),
    nn.Linear(84, 10)
)

次に、我々は、単一チャンネルデータを構成する各層の形状からの出力で計算するために、サンプル28、及び層によって、フロント層の高さと幅です。

print
X = torch.randn(size=(1,1,28,28), dtype = torch.float32)
for layer in net:
    X = layer(X)
    print(layer.__class__.__name__,'output shape: \t',X.shape)

每层的尺寸输出
リシェイプ出力形状:torch.Size([1、1、28、28])
Conv2d出力形状:torch.Size([1、6、28、28])
シグモイド出力形状:torch.Size([ 1、6、28、28])
AvgPool2d出力形状:torch.Size([1、6、14、14])
Conv2d出力形状:torch.Size([1、16、10、10])
シグモイド出力形状:トーチ.Size([1、16、10、10])
AvgPool2d出力形状:torch.Size([1、16、5、5])
平坦化出力形状:torch.Size([1、400])
線形出力形状:トーチ.Size([1、120])
シグモイド出力形状:torch.Size([1、120])
線形出力形状:torch.Size([1、84])
シグモイド出力形状:torch.Size([1]、[84] )
リニア出力形状:torch.Size([1]、[10])
これは、入力層ブロック畳み込み高さで見ることができ、幅は、層毎に減少します。畳み込み層の高さと幅の使用は、それによって層のプールの高さと幅が半減するが、高さと幅、それぞれ4を減少が、5畳み込みカーネルである1から16までのチャンネルの数。層は完全にはカテゴリ10の画像数になるまで、出力層の数を減らす接続されています。
ここに画像を挿入説明

データとモデル・トレインへのアクセス

LeNetモデルを実現します。ファッション-MNIST我々はまだ、訓練データセットとして使用します。

# 数据
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(
    batch_size=batch_size, root='/home/kesci/input/FashionMNIST2065')
print(len(train_iter))

画像データを表示するために余分な部分を追加

#数据展示
import matplotlib.pyplot as plt
def show_fashion_mnist(images, labels):
    d2l.use_svg_display()
    # 这里的_表示我们忽略(不使用)的变量
    _, figs = plt.subplots(1, len(images), figsize=(12, 12))
    for f, img, lbl in zip(figs, images, labels):
        f.imshow(img.view((28, 28)).numpy())
        f.set_title(lbl)
        f.axes.get_xaxis().set_visible(False)
        f.axes.get_yaxis().set_visible(False)
    plt.show()

for Xdata,ylabel in train_iter:
    break
X, y = [], []
for i in range(10):
    print(Xdata[i].shape,ylabel[i].numpy())
    X.append(Xdata[i]) # 将第i个feature加到X中
    y.append(ylabel[i].numpy()) # 将第i个label加到y中
show_fashion_mnist(X, y)

torch.Size([1、28、28])。3
torch.Size([1、28、28])。8
torch.Size([1、28、28])。1
torch.Size([1、28、28] )。4
torch.Size([1、28、28])0
torch.Size([1、28、28])0
torch.Size([1、28、28])。4
torch.Size([1、28、 28])。9
torch.Size([1、28、28])。4
torch.Size([1、28、28])。7
ここに画像を挿入説明
、多層パーセプトロンより機密複雑なコンピューティング畳み込みニューラルネットワークとして、推奨算出GPUアクセラレーションを使用して。それ以外の場合は、まだCPUを使用し、0:成功した利用CUDA場合、我々は、GPUを使用できるかどうかを確認してください。

# This function has been saved in the d2l package for future use
#use GPU
def try_gpu():
    """If GPU is available, return torch.device as cuda:0; else return torch.device as cpu."""
    if torch.cuda.is_available():
        device = torch.device('cuda:0')
    else:
        device = torch.device('cpu')
    return device

device = try_gpu()
device

data_iterの精度にネットモデル・データ・セットを計算するために使用されるevaluate_accuracy機能を実現します。

#计算准确率
'''
(1). net.train()
  启用 BatchNormalization 和 Dropout,将BatchNormalization和Dropout置为True
(2). net.eval()
不启用 BatchNormalization 和 Dropout,将BatchNormalization和Dropout置为False
'''

def evaluate_accuracy(data_iter, net,device=torch.device('cpu')):
    """Evaluate accuracy of a model on the given data set."""
    acc_sum,n = torch.tensor([0],dtype=torch.float32,device=device),0
    for X,y in data_iter:
        # If device is the GPU, copy the data to the GPU.
        X,y = X.to(device),y.to(device)
        net.eval()
        with torch.no_grad():
            y = y.long()
            acc_sum += torch.sum((torch.argmax(net(X), dim=1) == y))  #[[0.2 ,0.4 ,0.5 ,0.6 ,0.8] ,[ 0.1,0.2 ,0.4 ,0.3 ,0.1]] => [ 4 , 2 ]
            n += y.shape[0]
    return acc_sum.item()/n

私たちは、モデルのトレーニングに使用する関数のtrain_ch5を定義します。

#训练函数
def train_ch5(net, train_iter, test_iter,criterion, num_epochs, batch_size, device,lr=None):
    """Train and evaluate a model with CPU or GPU."""
    print('training on', device)
    net.to(device)
    optimizer = optim.SGD(net.parameters(), lr=lr)
    for epoch in range(num_epochs):
        train_l_sum = torch.tensor([0.0],dtype=torch.float32,device=device)
        train_acc_sum = torch.tensor([0.0],dtype=torch.float32,device=device)
        n, start = 0, time.time()
        for X, y in train_iter:
            net.train()
            
            optimizer.zero_grad()
            X,y = X.to(device),y.to(device) 
            y_hat = net(X)
            loss = criterion(y_hat, y)
            loss.backward()
            optimizer.step()
            
            with torch.no_grad():
                y = y.long()
                train_l_sum += loss.float()
                train_acc_sum += (torch.sum((torch.argmax(y_hat, dim=1) == y))).float()
                n += y.shape[0]
        test_acc = evaluate_accuracy(test_iter, net,device)
        print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f, '
              'time %.1f sec'
              % (epoch + 1, train_l_sum/n, train_acc_sum/n, test_acc,
                 time.time() - start))

上記、およびランダム初期化ザビエルを使用して:我々はデバイス装置(0 CPUやCUDA)に対応するモデルパラメータを再初期化します。損失関数とトレーニングアルゴリズムは依然としてクロスエントロピー損失関数と確率的勾配降下法の少量を使用しています。

# 训练
lr, num_epochs = 0.9, 10

def init_weights(m):
    if type(m) == nn.Linear or type(m) == nn.Conv2d:
        torch.nn.init.xavier_uniform_(m.weight)

net.apply(init_weights)
net = net.to(device)

criterion = nn.CrossEntropyLoss()   #交叉熵描述了两个概率分布之间的距离,交叉熵越小说明两者之间越接近
train_ch5(net, train_iter, test_iter, criterion,num_epochs, batch_size,device, lr)
# test
for testdata,testlabe in test_iter:
    testdata,testlabe = testdata.to(device),testlabe.to(device)
    break
print(testdata.shape,testlabe.shape)
net.eval()
y_pre = net(testdata)
print(torch.argmax(y_pre,dim=1)[:10])
print(testlabe[:10])

要約:

畳み込みニューラルネットワークは、畳み込み層を含むネットワークです。LeNet交互層と最大プール畳み込みコンタクト層画像分類のための完全に接続層。

公開された12元の記事 ウォンの賞賛0 ビュー267

おすすめ

転載: blog.csdn.net/inventertom/article/details/104634916