CNN Класификация на изображения в TensorFlow със стъпки и примери
Какво е конволюционна невронна мрежа?
Конволюционна невронна мрежа, известен също като convnets или CNN, е добре познат метод в приложенията за компютърно зрение. Това е клас дълбоки невронни мрежи, които се използват за анализ на визуални изображения. Този тип архитектура е доминираща за разпознаване на обекти от картина или видео. Използва се в приложения като разпознаване на изображения или видео, невронна езикова обработка и др.
Archiструктура на конволюционна невронна мрежа
Помислете за Facebook преди няколко години, след като сте качили снимка в профила си, бяхте помолени да добавите име към лицето на снимката ръчно. В наши дни Facebook използва convnet, за да маркира автоматично вашия приятел на снимката.
Конволюционната невронна мрежа за класифициране на изображения не е много трудна за разбиране. Входното изображение се обработва по време на фазата на навиване и по-късно му се приписва етикет.
Типична convnet архитектура може да бъде обобщена на снимката по-долу. Първо, изображението се изпраща към мрежата; това се нарича входно изображение. След това входното изображение преминава през безкраен брой стъпки; това е конволюционната част от мрежата. И накрая, невронната мрежа може да предвиди цифрата на изображението.

Изображението се състои от масив от пиксели с височина и ширина. Изображение в нива на сивото има само един канал, докато цветното изображение има три канала (всеки един за червено, зелено и синьо). Един канал е подреден един върху друг. В този урок ще използвате изображение в сива скала само с един канал. Всеки пиксел има стойност от 0 до 255, за да отрази интензитета на цвета. Например, пиксел, равен на 0, ще покаже бял цвят, докато пиксел със стойност, близка до 255, ще бъде по-тъмен.
Нека да разгледаме изображение, съхранено в Набор от данни MNIST. Картината по-долу показва как да представите картината отляво в матричен формат. Имайте предвид, че оригиналната матрица е стандартизирана да бъде между 0 и 1. За по-тъмен цвят стойността в матрицата е около 0.9, докато белите пиксели имат стойност 0.
Конволюционна операция
Най-критичният компонент в модела е конволюционният слой. Тази част има за цел да намали размера на изображението за по-бързи изчисления на теглата и да подобри обобщаването му.
По време на конволюционната част мрежата запазва основните характеристики на изображението и изключва неуместния шум. Например, моделът се учи как да разпознава слон от снимка с планина на заден план. Ако използвате традиционна невронна мрежа, моделът ще присвои тегло на всички пиксели, включително тези от планината, което не е от съществено значение и може да подведе мрежата.
Вместо това, а Keras конволюционната невронна мрежа ще използва математическа техника, за да извлече само най-подходящите пиксели. Тази математическа операция се нарича конволюция. Тази техника позволява на мрежата да научи все по-сложни характеристики на всеки слой. Конволюцията разделя матрицата на малки части, за да научи най-съществените елементи във всяка част.
Компоненти на конволюционна невронна мрежа (ConvNet или CNN)
Има четири компонента на Convnets
- Извивка
- Нелинейност (ReLU)
- Pooling или Подизвадка
- Класификация (напълно свързан слой)
Извивка
Целта на конволюцията е да извлече характеристиките на обекта върху изображението локално. Това означава, че мрежата ще научи специфични модели в картината и ще може да я разпознае навсякъде в картината.
Конволюцията е умножение по елементи. Концепцията е лесна за разбиране. Компютърът ще сканира част от изображението, обикновено с размери 3×3 и ще го умножи във филтър. Резултатът от умножението по елементи се нарича карта на характеристики. Тази стъпка се повтаря, докато цялото изображение бъде сканирано. Имайте предвид, че след навиването размерът на изображението се намалява.
По-долу има URL, за да видите в действие как работи конволюцията.
Има много налични канали. По-долу сме изброили някои от каналите. Можете да видите, че всеки филтър има специфична цел. Забележка, на снимката по-долу; ядрото е синоним на филтъра.
Аритметика зад конволюцията
Конволюционната фаза ще приложи филтъра върху малък масив от пиксели в картината. Филтърът ще се движи по входното изображение с обща форма 3×3 или 5×5. Това означава, че мрежата ще плъзне тези прозорци през цялото входно изображение и ще изчисли намотката. Изображението по-долу показва как работи конволюцията. Размерът на пластира е 3×3, а изходната матрица е резултат от поелементната операция между матрицата на изображението и филтъра.
Забелязвате, че ширината и височината на изхода може да се различават от ширината и височината на входа. Това се случва поради граничния ефект.
Граничен ефект
Изображението има карта с функции 5×5 и филтър 3×3. Има само един прозорец в центъра, където филтърът може да екранира решетка 3×3. Изходната карта на характеристиките ще се свие с две плочки заедно с измерение 3×3.
За да получите същото изходно измерение като входното измерение, трябва да добавите подложка. Подпълването се състои от добавяне на правилния брой редове и колони от всяка страна на матрицата. Това ще позволи центрирането на намотката във всяка входна плочка. На изображението по-долу входно/изходната матрица има същия размер 5×5
Когато дефинирате мрежата, извитите функции се контролират от три параметъра:
- Дълбочина: Определя броя на филтрите, които да се прилагат по време на свиването. В предишния пример видяхте дълбочина 1, което означава, че се използва само един филтър. В повечето случаи има повече от един филтър. Картината по-долу показва операциите, извършени в ситуация с три филтъра
- Крачка: Определя броя на „скока на пиксела“ между два среза. Ако стъпката е равна на 1, прозорците ще се движат с разпределение на един пиксел. Ако крачката е равна на две, прозорците ще скочат с 2 пиксела. Ако увеличите крачката, ще имате по-малки карти на характеристиките.
Примерна стъпка 1
крачка 2
- Нулева подплата: Подпълването е операция за добавяне на съответен брой редове и колони от всяка страна на картите на входните характеристики. В този случай изходът има същото измерение като входа.
Нелинейност (ReLU)
В края на операцията за навиване, изходът е обект на функция за активиране, за да позволи нелинейност. Обичайната функция за активиране на convnet е Relu. Всички пиксели с отрицателна стойност ще бъдат заменени с нула.
Pooling OperaАЦИ
Тази стъпка е лесна за разбиране. Целта на обединяването е да се намали размерността на входното изображение. Стъпките се правят, за да се намали изчислителната сложност на операцията. Чрез намаляване на размерността, мрежата има по-ниски тегла за изчисляване, така че предотвратява пренастройването.
На този етап трябва да определите размера и крачката. Стандартен начин за обединяване на входното изображение е да се използва максималната стойност на картата на характеристиките. Вижте снимката по-долу. „Обединяването“ ще екранира четири подматрица на картата на характеристиките 4×4 и ще върне максималната стойност. Обединяването взема максималната стойност на масив 2×2 и след това премества тези прозорци с два пиксела. Например, първата подматрица е [3,1,3,2], обединяването ще върне максимума, който е 3.
Има друга операция за обединяване, като средната стойност.
Тази операция агресивно намалява размера на картата на характеристиките
Напълно свързани слоеве
Последната стъпка се състои в изграждането на традиционен изкуствена невронна мрежа както направихте в предишния урок. Свързвате всички неврони от предишния слой към следващия слой. Използвате функция за активиране на softmax, за да класифицирате числото на входното изображение.
Обзор:
Конволюционната невронна мрежа TensorFlow компилира различни слоеве, преди да направи прогноза. Невронната мрежа има:
- Конволюционен слой
- Функция Relu за активиране
- Pooling слой
- Плътно свързан слой
Конволюционните слоеве прилагат различни филтри върху подрегион на картината. Функцията за активиране на Relu добавя нелинейност, а обединените слоеве намаляват размерността на картите на характеристиките.
Всички тези слоеве извличат важна информация от изображенията. Най-накрая картата на характеристиките се подава към първичен напълно свързан слой с функция softmax, за да се направи прогноза.
Обучете CNN с TensorFlow
Сега, след като сте запознати с градивния елемент на convnets, вие сте готови да изградите такъв TensorFlow. Ще използваме набора от данни на MNIST за класификация на изображения на CNN.
Подготовката на данните е същата като в предишния урок. Можете да стартирате кодовете и да преминете директно към архитектурата на CNN.
Ще следвате стъпките по-долу за класифициране на изображения с помощта на CNN:
Стъпка 1: Качете набор от данни
Стъпка 2: Входен слой
Стъпка 3: Конволюционен слой
Стъпка 4: Pooling слой
Стъпка 5: Втори конволюционен слой и Pooling Слой
Стъпка 6: Плътен слой
Стъпка 7: Logit слой
Стъпка 1: Качете набор от данни
Наборът от данни MNIST е достъпен със scikit, за да научите това URL. Моля, изтеглете го и го съхранете в Изтегляния. Можете да го качите с fetch_mldata('MNIST original').
Създайте набор от влак/тест
Трябва да разделите набора от данни с train_test_split
Мащабирайте функциите
И накрая, можете да мащабирате функцията с MinMaxScaler, както е показано в класификацията на изображението по-долу, като използвате примера на TensorFlow CNN.
import numpy as np import tensorflow as tf from sklearn.datasets import fetch_mldata #Change USERNAME by the username of your machine ## Windows USER mnist = fetch_mldata('C:\\Users\\USERNAME\\Downloads\\MNIST original') ## Mac User mnist = fetch_mldata('/Users/USERNAME/Downloads/MNIST original') print(mnist.data.shape) print(mnist.target.shape) from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(mnist.data, mnist.target, test_size=0.2, random_state=42) y_train = y_train.astype(int) y_test = y_test.astype(int) batch_size =len(X_train) print(X_train.shape, y_train.shape,y_test.shape ) ## resclae from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler() # Train X_train_scaled = scaler.fit_transform(X_train.astype(np.float64)) # test X_test_scaled = scaler.fit_transform(X_test.astype(np.float64)) feature_columns = [tf.feature_column.numeric_column('x', shape=X_train_scaled.shape[1:])] X_train_scaled.shape[1:]
Дефинирайте CNN
CNN използва филтри върху необработения пиксел на изображение, за да научи детайлен модел в сравнение с глобалния модел с традиционна невронна мрежа. За да създадете CNN, трябва да дефинирате:
- Конволюционен слой: Приложете n на брой филтри към картата на характеристиките. След конволюцията трябва да използвате функция за активиране на Relu, за да добавите нелинейност към мрежата.
- Pooling слой: Следващата стъпка след конволюцията е намаляване на семплирането на макс. Целта е да се намали размерността на картата на характеристиките, за да се предотврати пренастройването и да се подобри скоростта на изчисление. Максималното обединяване е конвенционалната техника, която разделя картите на характеристиките на подрегиони (обикновено с размер 2×2) и запазва само максималните стойности.
- Напълно свързани слоеве: Всички неврони от предишните слоеве са свързани със следващите слоеве. CNN ще класифицира етикета според характеристиките от конволюционните слоеве и намален със слоя за обединяване.
CNN архитектура
- Конволюционен слой: Прилага 14 филтъра 5×5 (извличащи подрегиони 5×5 пиксела), с функция за активиране на ReLU
- Pooling Слой: Извършва максимално обединяване с филтър 2×2 и стъпка 2 (което указва, че обединените региони не се припокриват)
- Конволюционен слой: Прилага 36 5×5 филтъра с функция за активиране ReLU
- Pooling Слой #2: Отново, извършва максимално обединяване с филтър 2×2 и стъпка от 2
- 1,764 неврона, със степен на регулиране на отпадането от 0.4 (вероятност от 0.4, че всеки даден елемент ще бъде изпуснат по време на обучение)
- Плътен слой (Logits Layer): 10 неврона, по един за всеки цифрен целеви клас (0–9).
Има три важни модула, които да използвате за създаване на CNN:
- conv2d(). Конструира двуизмерен конволюционен слой с броя на филтрите, размера на ядрото на филтъра, подложката и функцията за активиране като аргументи.
- max_pooling2d(). Конструира двуизмерен обединяващ слой с помощта на алгоритъма за максимално обединяване.
- dense(). Изгражда плътен слой със скритите слоеве и единици
Ще дефинирате функция за изграждане на CNN. Нека видим подробно как да конструираме всеки градивен елемент, преди да обвием всичко заедно във функцията.
Стъпка 2: Входен слой
def cnn_model_fn(features, labels, mode): input_layer = tf.reshape(tensor = features["x"],shape =[-1, 28, 28, 1])
Трябва да дефинирате тензор с формата на данните. За целта можете да използвате модула tf.reshape. В този модул трябва да декларирате тензора за преоформяне и формата на тензора. Първият аргумент е характеристиките на данните, които са дефинирани в аргумента на функцията.
Една картина има височина, ширина и канал. Наборът от данни MNIST е монохронна картина с размер 28×28. Задаваме размера на партидата на -1 в аргумента за форма, така че да приеме формата на характеристиките ["x"]. Предимството е да настроите хиперпараметрите за размера на партидата да се настройват. Ако размерът на партидата е зададен на 7, тогава тензорът ще подаде 5,488 стойности (28*28*7).
Стъпка 3: Конволюционен слой
# first Convolutional Layer conv1 = tf.layers.conv2d( inputs=input_layer, filters=14, kernel_size=[5, 5], padding="same", activation=tf.nn.relu)
Първият конволюционен слой има 14 филтъра с размер на ядрото 5×5 със същата подложка. Една и съща подложка означава, че както изходният, така и входният тензор трябва да имат еднаква височина и ширина. Tensorflow ще добави нули към редовете и колоните, за да осигури същия размер.
Използвате функцията за активиране на Relu. Изходният размер ще бъде [28, 28, 14].
Стъпка 4: Pooling слой
Следващата стъпка след конволюцията е изчислението на обединяването. Обединяването на изчисленията ще намали размерността на данните. Можете да използвате модула max_pooling2d с размер 2×2 и стъпка 2. Използвате предишния слой като вход. Изходният размер ще бъде [batch_size, 14, 14, 14]
# first Pooling Layer pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
Стъпка 5: Втори конволюционен слой и Pooling Слой
Вторият конволюционен слой има 32 филтъра с изходен размер [batch_size, 14, 14, 32]. Обединяващият слой има същия размер като преди и изходната форма е [batch_size, 14, 14, 18].
conv2 = tf.layers.conv2d( inputs=pool1, filters=36, kernel_size=[5, 5], padding="same", activation=tf.nn.relu) pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)
Стъпка 6: Плътен слой
След това трябва да дефинирате напълно свързания слой. Картата на характеристиките трябва да бъде изравнена, преди да се свърже с плътния слой. Можете да използвате преоформянето на модула с размер 7*7*36.
Плътният слой ще свързва 1764 неврона. Добавяте функция за активиране на Relu. Освен това добавяте член за регулиране на отпадане със скорост 0.3, което означава, че 30 процента от теглата ще бъдат зададени на 0. Имайте предвид, че отпадането се извършва само по време на фазата на обучение. Функцията cnn_model_fn има режим на аргумент, за да декларира дали моделът трябва да бъде обучен или да оцени, както е показано в примера TensorFlow за класификация на изображения на CNN по-долу.
pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 36]) dense = tf.layers.dense(inputs=pool2_flat, units=7 * 7 * 36, activation=tf.nn.relu) dropout = tf.layers.dropout( inputs=dense, rate=0.3, training=mode == tf.estimator.ModeKeys.TRAIN)
Стъпка 7: Logit слой
Накрая в примера за класификация на изображението TensorFlow можете да дефинирате последния слой с прогнозата на модела. Изходната форма е равна на размера на партидата и 10, общия брой изображения.
# Logits Layer logits = tf.layers.dense(inputs=dropout, units=10)
Можете да създадете речник, съдържащ класовете и вероятността за всеки клас. Модулът tf.argmax() с връща най-високата стойност, ако слоевете logit. Функцията softmax връща вероятността за всеки клас.
predictions = { # Generate predictions "classes": tf.argmax(input=logits, axis=1), "probabilities": tf.nn.softmax(logits, name="softmax_tensor") }
Искате да върнете прогнозата от речника само когато режимът е зададен на прогноза. Добавяте тези кодове, за да изведете прогнозите
if mode == tf.estimator.ModeKeys.PREDICT: return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)
Следващата стъпка се състои в изчисляване на загубата на модела. В последния урок научихте, че функцията на загуба за многокласов модел е кръстосана ентропия. Загубата се изчислява лесно със следния код:
# Calculate Loss (for both TRAIN and EVAL modes) loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)
Последната стъпка от примера на TensorFlow CNN е да се оптимизира моделът, тоест да се намерят най-добрите стойности на теглата. За това използвате оптимизатор за градиентно спускане със скорост на обучение от 0.001. Целта е да се минимизират загубите
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001) train_op = optimizer.minimize( loss=loss, global_step=tf.train.get_global_step())
Приключихте със CNN. Въпреки това искате да покажете показателите за ефективност по време на режима на оценка. Показателите за ефективност за многокласов модел са показателите за точност. Tensorflow е оборудван с модул за точност с два аргумента, етикетите и прогнозираните стойности.
eval_metric_ops = { "accuracy": tf.metrics.accuracy(labels=labels, predictions=predictions["classes"])} return tf.estimator.EstimatorSpec(mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)
Това е. Създадохте първия си CNN и сте готови да обвиете всичко във функция, за да я използвате за обучение и оценка на модела.
def cnn_model_fn(features, labels, mode): """Model function for CNN.""" # Input Layer input_layer = tf.reshape(features["x"], [-1, 28, 28, 1]) # Convolutional Layer conv1 = tf.layers.conv2d( inputs=input_layer, filters=32, kernel_size=[5, 5], padding="same", activation=tf.nn.relu) # Pooling Layer pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2) # Convolutional Layer #2 and Pooling Layer conv2 = tf.layers.conv2d( inputs=pool1, filters=36, kernel_size=[5, 5], padding="same", activation=tf.nn.relu) pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2) # Dense Layer pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 36]) dense = tf.layers.dense(inputs=pool2_flat, units=7 * 7 * 36, activation=tf.nn.relu) dropout = tf.layers.dropout( inputs=dense, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN) # Logits Layer logits = tf.layers.dense(inputs=dropout, units=10) predictions = { # Generate predictions (for PREDICT and EVAL mode) "classes": tf.argmax(input=logits, axis=1), "probabilities": tf.nn.softmax(logits, name="softmax_tensor") } if mode == tf.estimator.ModeKeys.PREDICT: return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions) # Calculate Loss loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits) # Configure the Training Op (for TRAIN mode) if mode == tf.estimator.ModeKeys.TRAIN: optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001) train_op = optimizer.minimize( loss=loss, global_step=tf.train.get_global_step()) return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op) # Add evaluation metrics Evaluation mode eval_metric_ops = { "accuracy": tf.metrics.accuracy( labels=labels, predictions=predictions["classes"])} return tf.estimator.EstimatorSpec( mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)
Стъпките по-долу са същите като предишните уроци.
Първо, дефинирате оценител с модела на CNN за класификация на изображения.
# Create the Estimator mnist_classifier = tf.estimator.Estimator( model_fn=cnn_model_fn, model_dir="train/mnist_convnet_model")
Обучението на CNN отнема много пъти, следователно вие създавате кука за регистриране, за да съхранявате стойностите на слоевете softmax на всеки 50 итерации.
# Set up logging for predictions tensors_to_log = {"probabilities": "softmax_tensor"} logging_hook = tf.train.LoggingTensorHook(tensors=tensors_to_log, every_n_iter=50)
Готови сте да оцените модела. Задавате размер на партида от 100 и разбърквате данните. Обърнете внимание, че задаваме стъпки за обучение от 16.000 XNUMX, може да отнеме много време за обучение. Бъдете търпеливи.
# Train the model train_input_fn = tf.estimator.inputs.numpy_input_fn( x={"x": X_train_scaled}, y=y_train, batch_size=100, num_epochs=None, shuffle=True) mnist_classifier.train( input_fn=train_input_fn, steps=16000, hooks=[logging_hook])
Сега, когато моделът е трениран, можете да го оцените и да отпечатате резултатите
# Evaluate the model and print results eval_input_fn = tf.estimator.inputs.numpy_input_fn( x={"x": X_test_scaled}, y=y_test, num_epochs=1, shuffle=False) eval_results = mnist_classifier.evaluate(input_fn=eval_input_fn) print(eval_results)
INFO:tensorflow:Calling model_fn. INFO:tensorflow:Done calling model_fn. INFO:tensorflow:Starting evaluation at 2018-08-05-12:52:41 INFO:tensorflow:Graph was finalized. INFO:tensorflow:Restoring parameters from train/mnist_convnet_model/model.ckpt-15652 INFO:tensorflow:Running local_init_op. INFO:tensorflow:Done running local_init_op. INFO:tensorflow:Finished evaluation at 2018-08-05-12:52:56 INFO:tensorflow:Saving dict for global step 15652: accuracy = 0.9589286, global_step = 15652, loss = 0.13894269 {'accuracy': 0.9689286, 'loss': 0.13894269, 'global_step': 15652}
С текущата архитектура получавате точност от 97%. Можете да промените архитектурата, размера на партидата и броя на итерациите, за да подобрите точността. Невронната мрежа на CNN се представи много по-добре от ANN или логистичната регресия. В урока за изкуствена невронна мрежа имахте точност от 96%, което е по-ниско от CNN. Изпълненията на CNN са впечатляващи с по-голям имидж определенкакто по отношение на скоростта на изчисление, така и по отношение на точността.
Oбобщение
Конволюционната невронна мрежа работи много добре за оценка на картината. Този тип архитектура е доминираща за разпознаване на обекти от картина или видео.
За да създадете TensorFlow CNN, трябва да следвате седем стъпки:
Стъпка : Качване на набор от данни:
Наборът от данни MNIST е достъпен със scikit за обучение. Моля, изтеглете го и го съхранете в Изтегляния. Можете да го качите с fetch_mldata('MNIST original').
Стъпка : Входен слой:
Тази стъпка променя формата на данните. Формата е равна на корен квадратен от броя на пикселите. Например, ако една картина има 156 пиксела, тогава формата е 26×26. Трябва да посочите дали картината има цвят или не. Ако да, тогава сте имали 3 за формата- 3 за RGB-, в противен случай 1.
input_layer = tf.reshape(tensor = features["x"],shape =[-1, 28, 28, 1])
Стъпка : Конволюционен слой
След това трябва да създадете конволюционните слоеве. Прилагате различни филтри, за да позволите на мрежата да научи важна функция. Вие определяте размера на ядрото и броя на филтрите.
conv1 = tf.layers.conv2d( inputs=input_layer, filters=14, kernel_size=[5, 5], padding="same", activation=tf.nn.relu)
Стъпка : Pooling слой
В третата стъпка добавяте обединяващ слой. Този слой намалява размера на входа. Това се прави, като се вземе максималната стойност на подматрицата a. Например, ако подматрицата е [3,1,3,2], групирането ще върне максимума, който е 3.
pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
Стъпка : Добавете конволюционен слой и Pooling Слой
В тази стъпка можете да добавите колкото желаете conv слоеве и слоеве за обединяване. Google използва архитектура с повече от 20 conv слоя.
Стъпка : Плътен слой
Стъпка 6 изравнява предишната, за да създаде напълно свързани слоеве. В тази стъпка можете да използвате различна функция за активиране и да добавите ефект на отпадане.
pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 36]) dense = tf.layers.dense(inputs=pool2_flat, units=7 * 7 * 36, activation=tf.nn.relu) dropout = tf.layers.dropout( inputs=dense, rate=0.3, training=mode == tf.estimator.ModeKeys.TRAIN)
Стъпка : Logit слой
Последната стъпка е прогнозата.
logits = tf.layers.dense(inputs=dropout, units=10)