Mang-than-kinh-tich-chap

Giới thiệu

Mạng nơ-ron tích chập (CNN) cũng được tạo thành từ các nơ-ron, có trọng số và độ lệch có thể học được. Đó là lý do tại sao theo cách này, chúng giống như các mạng thần kinh (NN) thông thường.

Nếu chúng ta nhớ lại hoạt động của các NN thông thường, mỗi nơ-ron sẽ nhận được một hoặc nhiều đầu vào, lấy một tổng có trọng số và chuyển qua hàm kích hoạt để tạo ra đầu ra cuối cùng. Ở đây, câu hỏi đặt ra là nếu CNN và NN thông thường có nhiều điểm tương đồng như vậy thì điều gì khiến hai mạng này khác nhau?

Điều gì làm cho chúng khác biệt là việc xử lý dữ liệu đầu vào và các loại lớp? Cấu trúc của dữ liệu đầu vào bị bỏ qua trong NN thông thường và tất cả dữ liệu được chuyển đổi thành mảng 1-D trước khi đưa vào mạng.

Tuy nhiên, kiến ​​trúc Mạng thần kinh chuyển đổi có thể xem xét cấu trúc 2D của hình ảnh, xử lý chúng và cho phép nó trích xuất các thuộc tính dành riêng cho hình ảnh. Hơn nữa, CNN có lợi thế là có một hoặc nhiều lớp Convolutional và lớp gộp, là những khối xây dựng chính của CNN.

Các lớp này được theo sau bởi một hoặc nhiều lớp được kết nối đầy đủ như trong NN nhiều lớp tiêu chuẩn. Vì vậy, chúng ta có thể coi CNN là một trường hợp đặc biệt của các mạng được kết nối đầy đủ.

Kiến trúc Mạng thần kinh chuyển đổi (CNN)

Kiến trúc của CNN về cơ bản là một danh sách các lớp biến đổi khối lượng hình ảnh 3 chiều, tức là chiều rộng, chiều cao và chiều sâu thành khối lượng đầu ra 3 chiều. Một điểm quan trọng cần lưu ý ở đây là mọi nơ-ron trong lớp hiện tại được kết nối với một mảng nhỏ đầu ra từ lớp trước, giống như phủ một N*N lọc trên hình ảnh đầu vào.

Nó sử dụng M bộ lọc, về cơ bản là các công cụ trích xuất tính năng trích xuất các tính năng như cạnh, góc, v.v. Sau đây là các lớp [INPUT-CONV-RELU-POOL-FC] được sử dụng để xây dựng Mạng nơ-ron tích chập (CNN)−

  • INPUT− Đúng như tên gọi, lớp này chứa các giá trị pixel thô. Giá trị pixel thô có nghĩa là dữ liệu của hình ảnh. Ví dụ: INPUT [64×64×3] là hình ảnh RGB 3 kênh có chiều rộng 64, chiều cao 64 và chiều sâu 3.
  • CONV− Lớp này là một trong những khối xây dựng của CNN vì hầu hết tính toán được thực hiện trong lớp này. Ví dụ – nếu chúng tôi sử dụng 6 bộ lọc trên INPUT [64×64×3] được đề cập ở trên, điều này có thể dẫn đến âm lượng [64×64×6].
  • RELU−Còn được gọi là lớp đơn vị tuyến tính được chỉnh lưu, áp dụng hàm kích hoạt cho đầu ra của lớp trước. Theo cách khác, tính phi tuyến tính sẽ được RELU thêm vào mạng.
  • POOL− Lớp này, tức là lớp gộp là một khối xây dựng khác của CNN. Nhiệm vụ chính của lớp này là lấy mẫu xuống, nghĩa là nó hoạt động độc lập trên mọi lát cắt của đầu vào và thay đổi kích thước theo không gian.
  • FC− Nó được gọi là Lớp được kết nối đầy đủ hay cụ thể hơn là lớp đầu ra. Nó được sử dụng để tính điểm của lớp đầu ra và kết quả đầu ra là khối lượng có kích thước 1*1*L trong đó L là số tương ứng với điểm lớp.

Sơ đồ bên dưới thể hiện kiến ​​trúc điển hình của CNN

Kiến trúc Mạng thần kinh chuyển đổi

Tạo cấu trúc CNN

Chúng ta đã thấy kiến ​​trúc và những điều cơ bản của CNN, bây giờ chúng ta sẽ xây dựng mạng tích chập bằng CNTK. Ở đây, trước tiên chúng ta sẽ xem cách kết hợp cấu trúc của CNN và sau đó chúng ta sẽ xem cách huấn luyện các tham số của nó.

Cuối cùng, chúng ta sẽ thấy cách chúng ta có thể cải thiện mạng lưới thần kinh bằng cách thay đổi cấu trúc của nó bằng nhiều cách thiết lập lớp khác nhau. Chúng tôi sẽ sử dụng tập dữ liệu hình ảnh MNIST.

Vì vậy, trước tiên hãy tạo cấu trúc CNN. Nói chung, khi chúng tôi xây dựng CNN để nhận dạng các mẫu trong hình ảnh, chúng tôi thực hiện như sau−

  • Chúng tôi sử dụng kết hợp các lớp tích chập và gộp.
  • Một hoặc nhiều lớp ẩn ở cuối mạng.
  • Cuối cùng, chúng tôi hoàn thiện mạng bằng lớp softmax cho mục đích phân loại.

Với sự trợ giúp của các bước sau, chúng ta có thể xây dựng cấu trúc mạng−

Bước 1− Đầu tiên, chúng ta cần nhập các lớp cần thiết cho CNN. from cntk.layers import Convolution2D, Sequential, Dense, MaxPooling

Bước 2− Tiếp theo, chúng ta cần nhập các hàm kích hoạt cho CNN. from cntk.ops import log_softmax, relu

Bước 3− Sau đó để khởi tạo các lớp chập sau này, chúng ta cần nhập glorot_uniform_initializer như sau− from cntk.initializer import glorot_uniform

Bước 4− Tiếp theo, để tạo biến đầu vào, hãy nhập hàm input_variable. Và nhập hàm default_option để cấu hình NN dễ dàng hơn một chút. from cntk import input_variable, default_options

Bước 5− Bây giờ để lưu trữ hình ảnh đầu vào, hãy tạo một input_variable mới. Nó sẽ chứa ba kênh là đỏ, xanh lá cây và xanh lam. Nó sẽ có kích thước 28 x 28 pixel. features = input_variable((3,28,28))

Bước 6−Tiếp theo, chúng ta cần tạo một input_variable khác để lưu trữ các nhãn để dự đoán. labels = input_variable(10)

Bước 7− Bây giờ, chúng ta cần tạo default_option cho NN. Và chúng ta cần sử dụng glorot_uniform làm hàm khởi tạo. with default_options(initialization=glorot_uniform, activation=relu):

Bước 8− Tiếp theo, để thiết lập cấu trúc của NN, chúng ta cần tạo một Tuần tự mới< một tập hợp lớp i=3>.

Bước 9− Bây giờ chúng ta cần thêm lớp Convolutional2D với < cài đặt i=4>filter_shape trên 5 và cài đặt sải bước của 1< /span>. Ngoài ra, hãy bật phần đệm để hình ảnh được đệm để giữ nguyên kích thước ban đầu.Tuần tự, trong tập hợp lớp model = Sequential([Convolution2D(filter_shape=(5,5), strides=(1,1), num_filters=8, pad=True),

Bước 10− Bây giờ là lúc thêm lớp MaxPooling với filter_shape là 2 và cài đặt sải bước là 2 để nén hình ảnh xuống một nửa. MaxPooling(filter_shape=(2,2), strides=(2,2)),

Bước 11− Bây giờ, như chúng ta đã làm ở bước 9, chúng ta cần thêm một Convolutional2D khác lớp có cài đặt filter_shape là 5 và cài đặt sải bước là 1, hãy sử dụng 16 bộ lọc. Ngoài ra, hãy bật phần đệm để giữ lại kích thước của hình ảnh do lớp gộp trước đó tạo ra. Convolution2D(filter_shape=(5,5), strides=(1,1), num_filters=16, pad=True),

Bước 12− Bây giờ, như chúng ta đã làm ở bước 10, hãy thêm một lớp MaxPooling khác với một filter_shape cài đặt 3 và sải bước cài đặt 3 để giảm hình ảnh xuống một phần ba. MaxPooling(filter_shape=(3,3), strides=(3,3)),

Bước 13− Cuối cùng, thêm một Lớp dày đặc với 10 nơ-ron cho 10 lớp có thể mà mạng có thể dự đoán. Để biến mạng thành mô hình phân loại, hãy sử dụng chức năng kích hoạt log_siftmax. Dense(10, activation=log_softmax)])Ví dụ hoàn chỉnh để tạo cấu trúc 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)

Đào tạo CNN bằng hình ảnh

Khi chúng ta đã tạo xong cấu trúc của mạng, đã đến lúc đào tạo mạng. Nhưng trước khi bắt đầu đào tạo mạng, chúng ta cần thiết lập các nguồn minibatch, vì việc đào tạo một NN hoạt động với hình ảnh đòi hỏi nhiều bộ nhớ hơn hầu hết các máy tính.

Chúng tôi đã tạo nguồn minibatch trong các phần trước. Sau đây là mã Python để thiết lập hai nguồn minibatch –

Vì có hàm create_datasource nên giờ đây chúng tôi có thể tạo hai nguồn dữ liệu riêng biệt (một nguồn đào tạo và thử nghiệm) để đào tạo mô hình.< /span>

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

Bây giờ, khi chúng ta đã chuẩn bị xong các hình ảnh, chúng ta có thể bắt đầu huấn luyện NN của mình. Như chúng ta đã làm ở các phần trước, chúng ta có thể sử dụng phương thức train trên hàm loss để bắt đầu quá trình huấn luyện. Sau đây là mã cho việc này

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)

Với sự trợ giúp của mã trước đó, chúng tôi đã thiết lập phần mất và phần học cho NN. Đoạn mã sau sẽ huấn luyện và xác thực 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])

Ví dụ triển khai hoàn chỉnh

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])

đầu ra :

-------------------------------------------------------------------
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
[………]

Biến đổi hình ảnh

Như chúng ta đã thấy, rất khó để huấn luyện NN được sử dụng để nhận dạng hình ảnh và chúng cũng cần rất nhiều dữ liệu để huấn luyện. Một vấn đề nữa là chúng có xu hướng quá phù hợp với hình ảnh được sử dụng trong quá trình đào tạo. Chúng ta hãy xem bằng một ví dụ, khi chúng ta có ảnh các khuôn mặt ở tư thế thẳng đứng, người mẫu của chúng ta sẽ gặp khó khăn trong việc nhận dạng các khuôn mặt bị xoay theo hướng khác.

Để khắc phục vấn đề này, chúng ta có thể sử dụng tính năng tăng cường hình ảnh và CNTK hỗ trợ các phép biến đổi cụ thể khi tạo nguồn minibatch cho hình ảnh. Chúng ta có thể sử dụng một số phép biến đổi như sau−

  • Chúng ta có thể cắt ngẫu nhiên các hình ảnh được sử dụng để đào tạo chỉ bằng một vài dòng mã.
  • Chúng ta cũng có thể sử dụng thang đo và màu sắc.

Hãy xem với sự trợ giúp của mã Python sau đây, cách chúng ta có thể thay đổi danh sách các phép biến đổi bằng cách đưa phép biến đổi cắt xén vào trong hàm được sử dụng để tạo nguồn minibatch trước đó

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)

Với sự trợ giúp của đoạn mã trên, chúng ta có thể nâng cao chức năng để bao gồm một tập hợp các biến đổi hình ảnh, để khi đào tạo, chúng ta có thể cắt hình ảnh một cách ngẫu nhiên để có được nhiều biến thể hơn của hình ảnh.

Xem thêm : CNTK – Mạng thần kinh tái phát

Trả lời