CNTK - Jaringan Neural Konvolusional

Dalam bab ini, mari kita pelajari cara membangun Jaringan Neural Konvolusional (CNN) di CNTK.

pengantar

Jaringan saraf konvolusional (CNN) juga terdiri dari neuron, yang memiliki bobot dan bias yang dapat dipelajari. Itulah mengapa dengan cara ini, mereka seperti jaringan saraf biasa (NN).

Jika kita mengingat cara kerja NN biasa, setiap neuron menerima satu atau lebih masukan, mengambil jumlah tertimbang dan melewati fungsi aktivasi untuk menghasilkan keluaran akhir. Di sini, muncul pertanyaan bahwa jika CNN dan NN biasa memiliki begitu banyak kesamaan, lalu apa yang membuat kedua jaringan ini berbeda satu sama lain?

Apa yang membuat mereka berbeda adalah perlakuan terhadap data masukan dan jenis lapisan? Struktur data masukan diabaikan dalam NN biasa dan semua data diubah menjadi larik 1-D sebelum memasukkannya ke dalam jaringan.

Namun, arsitektur Convolutional Neural Network dapat mempertimbangkan struktur 2D gambar, memprosesnya, dan memungkinkannya mengekstrak properti yang khusus untuk gambar. Selain itu, CNN memiliki keuntungan karena memiliki satu atau lebih lapisan Konvolusional dan lapisan penggabungan, yang merupakan blok penyusun utama CNN.

Lapisan ini diikuti oleh satu atau lebih lapisan yang terhubung sepenuhnya seperti pada NN multilayer standar. Jadi, kita dapat menganggap CNN, sebagai kasus khusus dari jaringan yang terhubung sepenuhnya.

Arsitektur Convolutional Neural Network (CNN)

Arsitektur CNN pada dasarnya adalah daftar lapisan yang mentransformasikan 3 dimensi, yaitu lebar, tinggi dan kedalaman volume citra menjadi volume keluaran 3 dimensi. Satu hal penting yang perlu diperhatikan di sini adalah bahwa, setiap neuron di lapisan saat ini terhubung ke patch kecil keluaran dari lapisan sebelumnya, yang seperti melapisi filter N * N pada gambar masukan.

Ini menggunakan filter M, yang pada dasarnya adalah ekstraktor fitur yang mengekstrak fitur seperti tepi, sudut, dan sebagainya. Berikut adalah lapisannya [INPUT-CONV-RELU-POOL-FC] yang digunakan untuk membangun jaringan saraf konvolusional (CNN) -

  • INPUT- Sesuai dengan namanya, layer ini menyimpan nilai piksel mentah. Nilai piksel mentah berarti data gambar apa adanya. Contoh, INPUT [64 × 64 × 3] adalah gambar RGB 3-saluran dengan lebar-64, tinggi-64 dan kedalaman-3.

  • CONV- Lapisan ini adalah salah satu blok penyusun CNN karena sebagian besar komputasi dilakukan di lapisan ini. Contoh - jika kita menggunakan 6 filter pada INPUT yang disebutkan di atas [64 × 64 × 3], ini mungkin menghasilkan volume [64 × 64 × 6].

  • RELU−Juga disebut lapisan unit linier tersearah, yang menerapkan fungsi aktivasi ke keluaran dari lapisan sebelumnya. Dengan cara lain, non-linearitas akan ditambahkan ke jaringan oleh RELU.

  • POOL- Lapisan ini, yaitu lapisan Pooling adalah salah satu blok penyusun CNN lainnya. Tugas utama lapisan ini adalah pengambilan sampel, yang berarti ia beroperasi secara independen pada setiap potongan masukan dan mengubah ukurannya secara spasial.

  • FC- Ini disebut lapisan Sepenuhnya Terhubung atau lebih khusus lagi lapisan keluaran. Ini digunakan untuk menghitung skor kelas keluaran dan keluaran yang dihasilkan adalah volume dengan ukuran 1 * 1 * L dimana L adalah angka yang sesuai dengan skor kelas.

Diagram di bawah ini mewakili arsitektur khas CNNs−

Membuat struktur CNN

Kami telah melihat arsitektur dan dasar-dasar CNN, sekarang kami akan membangun jaringan konvolusional menggunakan CNTK. Di sini, pertama-tama kita akan melihat bagaimana menyusun struktur CNN dan kemudian kita akan melihat bagaimana melatih parameternya.

Akhirnya kita akan melihat, bagaimana kita dapat meningkatkan jaringan saraf dengan mengubah strukturnya dengan berbagai pengaturan lapisan yang berbeda. Kami akan menggunakan dataset gambar MNIST.

Jadi, pertama-tama mari buat struktur CNN. Umumnya, ketika kita membangun CNN untuk mengenali pola dalam gambar, kita melakukan hal berikut-

  • Kami menggunakan kombinasi lapisan konvolusi dan penggabungan.

  • Satu atau lebih lapisan tersembunyi di ujung jaringan.

  • Akhirnya, kami menyelesaikan jaringan dengan lapisan softmax untuk tujuan klasifikasi.

Dengan bantuan langkah-langkah berikut, kita dapat membangun struktur jaringan−

Step 1- Pertama, kita perlu mengimpor lapisan yang diperlukan untuk CNN.

from cntk.layers import Convolution2D, Sequential, Dense, MaxPooling

Step 2- Selanjutnya, kita perlu mengimpor fungsi aktivasi untuk CNN.

from cntk.ops import log_softmax, relu

Step 3- Setelah itu untuk menginisialisasi lapisan konvolusional nanti, kita perlu mengimpor file glorot_uniform_initializer sebagai berikut-

from cntk.initializer import glorot_uniform

Step 4- Selanjutnya, untuk membuat variabel input, impor file input_variablefungsi. Dan impordefault_option fungsi, untuk membuat konfigurasi NN sedikit lebih mudah.

from cntk import input_variable, default_options

Step 5- Sekarang untuk menyimpan gambar masukan, buat yang baru input_variable. Ini akan berisi tiga saluran yaitu merah, hijau dan biru. Ini akan memiliki ukuran 28 kali 28 piksel.

features = input_variable((3,28,28))

Step 6−Selanjutnya, kita perlu membuat yang lain input_variable untuk menyimpan label yang akan diprediksi.

labels = input_variable(10)

Step 7- Sekarang, kita perlu membuat file default_optionuntuk NN. Dan, kita perlu menggunakanglorot_uniform sebagai fungsi inisialisasi.

with default_options(initialization=glorot_uniform, activation=relu):

Step 8- Selanjutnya, untuk mengatur struktur NN, kita perlu membuat yang baru Sequential set lapisan.

Step 9- Sekarang kita perlu menambahkan Convolutional2D lapisan dengan a filter_shape dari 5 dan a strides pengaturan 1, dalam Sequentialset lapisan. Selain itu, aktifkan pengisi, sehingga gambar dilengkapi bantalan untuk mempertahankan dimensi aslinya.

model = Sequential([
Convolution2D(filter_shape=(5,5), strides=(1,1), num_filters=8, pad=True),

Step 10- Sekarang saatnya menambahkan file MaxPooling lapisan dengan filter_shape dari 2, dan a strides pengaturan 2 untuk memampatkan gambar menjadi setengah.

MaxPooling(filter_shape=(2,2), strides=(2,2)),

Step 11- Sekarang, seperti yang kita lakukan di langkah 9, kita perlu menambahkan yang lain Convolutional2D lapisan dengan a filter_shape dari 5 dan a stridespengaturan 1, gunakan 16 filter. Selain itu, aktifkan pengisi, sehingga ukuran gambar yang dihasilkan oleh lapisan penggabungan sebelumnya harus dipertahankan.

Convolution2D(filter_shape=(5,5), strides=(1,1), num_filters=16, pad=True),

Step 12- Sekarang, seperti yang kita lakukan pada langkah 10, tambahkan lagi MaxPooling lapisan dengan a filter_shape dari 3 dan a strides pengaturan 3 untuk mengurangi gambar menjadi sepertiga.

MaxPooling(filter_shape=(3,3), strides=(3,3)),

Step 13- Terakhir, tambahkan lapisan Dense dengan sepuluh neuron untuk 10 kemungkinan kelas, jaringan dapat memprediksi. Untuk mengubah jaringan menjadi model klasifikasi, gunakan alog_siftmax fungsi aktivasi.

Dense(10, activation=log_softmax)
])

Contoh Lengkap untuk membuat struktur CNN

from cntk.layers import Convolution2D, Sequential, Dense, MaxPooling
from cntk.ops import log_softmax, relu
from cntk.initializer import glorot_uniform
from cntk import input_variable, default_options
features = input_variable((3,28,28))
labels = input_variable(10)
with default_options(initialization=glorot_uniform, activation=relu):
model = Sequential([
   Convolution2D(filter_shape=(5,5), strides=(1,1), num_filters=8, pad=True),
MaxPooling(filter_shape=(2,2), strides=(2,2)),
   Convolution2D(filter_shape=(5,5), strides=(1,1), num_filters=16, pad=True),
MaxPooling(filter_shape=(3,3), strides=(3,3)),
Dense(10, activation=log_softmax)
])
z = model(features)

Melatih CNN dengan gambar

Karena kita telah membuat struktur jaringan, inilah saatnya melatih jaringan. Tetapi sebelum memulai pelatihan jaringan kita, kita perlu menyiapkan sumber minibatch, karena melatih NN yang bekerja dengan gambar membutuhkan lebih banyak memori, daripada kebanyakan komputer.

Kami telah membuat sumber minibatch di bagian sebelumnya. Berikut adalah kode Python untuk mengatur dua sumber minibatch -

Seperti yang kita miliki create_datasource fungsi, sekarang kita dapat membuat dua sumber data terpisah (pelatihan dan pengujian) untuk melatih model.

train_datasource = create_datasource('mnist_train')
test_datasource = create_datasource('mnist_test', max_sweeps=1, train=False)

Sekarang, setelah kami menyiapkan gambar, kami dapat memulai pelatihan NN kami. Seperti yang kita lakukan di bagian sebelumnya, kita bisa menggunakan metode train pada fungsi kerugian untuk memulai pelatihan. Berikut adalah kode untuk ini -

from cntk import Function
from cntk.losses import cross_entropy_with_softmax
from cntk.metrics import classification_error
from cntk.learners import sgd
@Function
def criterion_factory(output, targets):
loss = cross_entropy_with_softmax(output, targets)
metric = classification_error(output, targets)
return loss, metric
loss = criterion_factory(z, labels)
learner = sgd(z.parameters, lr=0.2)

Dengan bantuan kode sebelumnya, kami telah menyiapkan loss dan pelajar untuk NN. Kode berikut akan melatih dan memvalidasi NN−

from cntk.logging import ProgressPrinter
from cntk.train import TestConfig
progress_writer = ProgressPrinter(0)
test_config = TestConfig(test_datasource)
input_map = {
   features: train_datasource.streams.features,
   labels: train_datasource.streams.labels
}
loss.train(train_datasource,
     max_epochs=10,
     minibatch_size=64,
     epoch_size=60000,
        parameter_learners=[learner],
     model_inputs_to_streams=input_map,
     callbacks=[progress_writer, test_config])

Contoh Implementasi Lengkap

from cntk.layers import Convolution2D, Sequential, Dense, MaxPooling
from cntk.ops import log_softmax, relu
from cntk.initializer import glorot_uniform
from cntk import input_variable, default_options
features = input_variable((3,28,28))
labels = input_variable(10)
with default_options(initialization=glorot_uniform, activation=relu):
model = Sequential([
   Convolution2D(filter_shape=(5,5), strides=(1,1), num_filters=8, pad=True),
MaxPooling(filter_shape=(2,2), strides=(2,2)),
   Convolution2D(filter_shape=(5,5), strides=(1,1), num_filters=16, pad=True),
MaxPooling(filter_shape=(3,3), strides=(3,3)),
Dense(10, activation=log_softmax)
])
z = model(features)
import os
from cntk.io import MinibatchSource, StreamDef, StreamDefs, ImageDeserializer, INFINITELY_REPEAT
import cntk.io.transforms as xforms
def create_datasource(folder, train=True, max_sweeps=INFINITELY_REPEAT):
   mapping_file = os.path.join(folder, 'mapping.bin')
   image_transforms = []
   if train:
    image_transforms += [
     xforms.crop(crop_type='randomside', side_ratio=0.8),
     xforms.scale(width=28, height=28, channels=3, interpolations='linear')
]
   stream_definitions = StreamDefs(
   features=StreamDef(field='image', transforms=image_transforms),
    labels=StreamDef(field='label', shape=10)
)
   deserializer = ImageDeserializer(mapping_file, stream_definitions)
return MinibatchSource(deserializer, max_sweeps=max_sweeps)
train_datasource = create_datasource('mnist_train')
test_datasource = create_datasource('mnist_test', max_sweeps=1, train=False)
from cntk import Function
from cntk.losses import cross_entropy_with_softmax
from cntk.metrics import classification_error
from cntk.learners import sgd
@Function
def criterion_factory(output, targets):
   loss = cross_entropy_with_softmax(output, targets)
   metric = classification_error(output, targets)
return loss, metric
loss = criterion_factory(z, labels)
learner = sgd(z.parameters, lr=0.2)
from cntk.logging import ProgressPrinter
from cntk.train import TestConfig
progress_writer = ProgressPrinter(0)
test_config = TestConfig(test_datasource)
input_map = {
   features: train_datasource.streams.features,
   labels: train_datasource.streams.labels
}
loss.train(train_datasource,
     max_epochs=10,
     minibatch_size=64,
     epoch_size=60000,
        parameter_learners=[learner],
     model_inputs_to_streams=input_map,
     callbacks=[progress_writer, test_config])

Keluaran

-------------------------------------------------------------------
average  since  average  since  examples
loss     last   metric   last
------------------------------------------------------
Learning rate per minibatch: 0.2
142      142      0.922   0.922    64
1.35e+06 1.51e+07 0.896   0.883    192
[………]

Transformasi gambar

Seperti yang telah kita lihat, sulit untuk melatih NN yang digunakan untuk pengenalan gambar dan, mereka juga membutuhkan banyak data untuk dilatih. Satu masalah lagi adalah, mereka cenderung menyesuaikan gambar yang digunakan selama pelatihan. Mari kita lihat dengan sebuah contoh, saat kita memiliki foto wajah dalam posisi tegak, model kita akan kesulitan mengenali wajah yang diputar ke arah lain.

Untuk mengatasi masalah tersebut, kita dapat menggunakan augmentasi gambar dan CNTK mendukung transformasi tertentu, saat membuat sumber minibatch untuk gambar. Kita dapat menggunakan beberapa transformasi sebagai berikut-

  • Kami dapat secara acak memotong gambar yang digunakan untuk pelatihan hanya dengan beberapa baris kode.

  • Kita juga bisa menggunakan skala dan warna.

Mari kita lihat dengan bantuan kode Python berikut, bagaimana kita dapat mengubah daftar transformasi dengan memasukkan transformasi pemangkasan dalam fungsi yang digunakan untuk membuat sumber minibatch sebelumnya.

import os
from cntk.io import MinibatchSource, StreamDef, StreamDefs, ImageDeserializer, INFINITELY_REPEAT
import cntk.io.transforms as xforms
def create_datasource(folder, train=True, max_sweeps=INFINITELY_REPEAT):
   mapping_file = os.path.join(folder, 'mapping.bin')
   image_transforms = []
   if train:
   image_transforms += [
     xforms.crop(crop_type='randomside', side_ratio=0.8),
xforms.scale(width=28, height=28, channels=3, interpolations='linear')
]
   stream_definitions = StreamDefs(
   features=StreamDef(field='image', transforms=image_transforms),
labels=StreamDef(field='label', shape=10)
)
   deserializer = ImageDeserializer(mapping_file, stream_definitions)
return MinibatchSource(deserializer, max_sweeps=max_sweeps)

Dengan bantuan kode di atas, kita dapat meningkatkan fungsi untuk menyertakan sekumpulan transformasi gambar, sehingga ketika akan dilatih kita dapat melakukan crop gambar secara acak, sehingga kita mendapatkan lebih banyak variasi gambar.