Аннотация: в этой статье в основном реализуются пользовательские случаи классификации изображений CNN с помощью Tensorflow + Opencv, которые могут решать проблемы классификации изображений в наших реальных статьях или на практике, а также проводить сравнительные эксперименты с алгоритмами классификации изображений машинного обучения.
Эта статья опубликована в сообществе Huawei Cloud Community "Tensorflow + Opencv реализует пользовательскую классификацию изображений CNN и сравнивает ее с классификацией изображений KNN.", по Истмаунт.
1. Классификация изображений
Классификация изображений — это проблема классификации содержимого изображений, которая использует компьютеры для количественного анализа изображений и разделения изображений или областей на изображениях на несколько категорий, чтобы заменить человеческое визуальное суждение. Традиционным методом классификации изображений является описание и обнаружение признаков.Такие традиционные методы могут быть эффективны для некоторой простой классификации изображений, но из-за сложности реальной ситуации традиционные методы классификации перегружены. Сегодня методы машинного обучения и глубокого обучения широко используются для решения задач классификации изображений, где основной задачей является присвоение набору входных изображений определенной метки в известной смеси категорий.
На изображении ниже модель классификации изображений возьмет одно изображение и будет состоять из 4 меток {кошка, собака, шляпа, кружка}, соответствующих вероятностям {0,6, 0,3, 0,05, 0,05}, где 0,6 представляет вероятность того, что изображение лейбл cat , остальное по аналогии. Изображение представляется в виде трехмерного массива. В этом примере изображение кошки имеет ширину 248 пикселей, высоту 400 пикселей и три цветовых канала (обычно называемых RGB) для красного, зеленого и синего цветов. Итак, изображение состоит из чисел 248x400x3 или всего 297600 чисел, каждое число представляет собой целое число от 0 (черное) до 255 (белое). Задача классификации изображений состоит в том, чтобы превратить эти около 300 000 чисел в одну метку, например «кошка».
Итак, как написать алгоритм классификации изображений? И как вы определяете кошек по такому количеству изображений? Принятый здесь метод аналогичен обучению детей видеть картинки и распознавать объекты.Давая много данных изображения, пусть модель продолжает изучать характеристики каждого класса. Перед обучением необходимо классифицировать и маркировать изображения обучающего набора, как показано на рисунке, включающего четыре категории кота, собаки, кружки и шляпы. В практической инженерии могут быть тысячи категорий объектов, и каждая категория будет иметь миллионы изображений.
Классификация изображений заключается в том, чтобы ввести массив значений пикселей для группы изображений, затем присвоить ему классификационную метку, построить модель алгоритма посредством обучения и обучения, а затем использовать модель для прогнозирования классификации изображений.Конкретный процесс выглядит следующим образом:
- входить:Входные данные содержат набор N изображений, каждое из которых помечено одной из K классификационных меток, и этот набор называется обучающим набором.
- учиться:Вторая задача — использовать обучающий набор для изучения особенностей каждого класса и построения обучающего классификатора или модели классификации.
- Оценка:Классификатор используется для прогнозирования метки классификации нового входного изображения и использования ее для оценки качества классификатора. Качество алгоритма классификации оценивается путем сравнения метки, предсказанной классификатором, с реальной меткой классификации изображения. Если классификационная метка, предсказанная классификатором, согласуется с реальной классификационной меткой изображения, прогноз правильный, в противном случае прогноз неверен.
Общие алгоритмы классификации включают наивные байесовские классификаторы, деревья решений, алгоритмы классификации K-ближайших соседей, машины опорных векторов, нейронные сети и алгоритмы классификации на основе правил, а также алгоритмы ансамблевого обучения для объединения методов одного класса, таких как бэгинг и бустинг. и другие.
2. Классификация изображений на основе алгоритма KNN
1. Алгоритм КНН
Алгоритм K-Nearest Neighbor Classifier (Классификатор K-Nearest Neighbor) представляет собой метод классификации на основе экземпляров, который является одним из самых простых и наиболее часто используемых методов в технологии классификации интеллектуального анализа данных. Основная идея этого алгоритма состоит в том, чтобы найти первые K выборок (как подобия), которые наиболее близки к расстоянию тестовой выборки (евклидову расстоянию) во всех обучающих выборках X из обучающих выборок, а затем выбрать K выборок с наименьшим расстояние от образцов, которые должны быть классифицированы как K ближайших соседей X, и для определения того, к какому классу образцов принадлежит большинство K образцов, считайте, что класс тестовых образцов принадлежит к этому классу образцов.
Теперь предположим, что необходимо определить, относится ли круговой узор на следующем рисунке к категории треугольника или квадрата. Алгоритм KNN используется для анализа следующим образом:
- Когда K=3, первый круг на рисунке содержит три фигуры, в том числе два треугольника и один квадрат, и этот круг классифицируется как треугольник.
- Когда K=5, второй круг содержит 5 фигур, 2 треугольника и 3 квадрата, и предполагается, что круг будет меткой квадрата с результатом голосования 3:2. Установка разных значений K может предсказать разные результаты.
Короче говоря, выборка принадлежит к тому же классу, что и большинство k ближайших соседей в наборе данных. Из его идеи видно, что KNN классифицируется путем измерения расстояния между различными собственными значениями, и при определении категории выборки он ссылается только на категорию k «соседних» выборок вокруг выборки. Следовательно, он больше подходит для работы со сценариями, в которых имеется много перекрывающихся наборов выборок, и в основном используется для прогнозного анализа, классификации текста, уменьшения размерности и другой обработки.
В пакете машинного обучения Sklearn KNN реализует класс NeighborsClassifier или алгоритм KNN для краткости. Способ построения такой:
KNeighborsClassifier(algorithm='ball_tree',
leaf_size=30,
metric='minkowski',
metric_params=None,
n_jobs=1,
n_neighbors=3,
p=2,
weights='uniform')
KNeighborsClassifier может установить 3 алгоритма: brute, kd_tree, ball_tree и установить для параметра значения K значение n_neighbors=3. Метод вызова следующий:
- from sklearn.neighbors import KNeighborsClassifier
- knn = KNeighborsClassifier (n_neighbors = 3, алгоритм = "ball_tree")
Он состоит из двух шагов:
- Обучение: nbrs.fit(данные, цель)
- Прогноз: pre = clf.predict(данные)
2. Набор данных
В этой части в основном используется пакет Scikit-Learn для обработки классификации изображений Python. Пакет расширений Scikit-Learn — это классический практичный пакет расширений для интеллектуального анализа данных и анализа данных Python, часто называемый аббревиатурой Sklearn. Модели машинного обучения в Scikit-Learn очень богаты, включая линейную регрессию, дерево решений, SVM, KMeans, KNN, PCA и т. д. Пользователи могут выбрать подходящую модель пакета расширения в соответствии с типом конкретной задачи анализа, чтобы для выполнения анализа данных процесс установки в основном реализуется через «pip install scikit-learn».
В эксперименте использовался набор данных Sort_1000pics, содержащий 1000 изображений и разделенный на 10 категорий, а именно: люди (категория 0), пляж (категория 1), здания (категория 2), грузовики (класс 3), динозавры (класс 4), Слоны (Класс 5), Цветы (Класс 6), Лошади (Класс 7), Горы (Класс 8) и Еда (Класс 9), 100 листов на категорию. как показано на рисунке.
Затем все типы изображений делятся на папки с именами от «0» до «9» в соответствии с соответствующими метками классов.Как показано на рисунке, каждая папка содержит 100 изображений, соответствующих одной и той же категории.
Например, папка с именем «6» содержит 100 изображений цветов, как показано на изображении ниже.
3. Классификация изображений KNN
Ниже приведен полный код для вызова алгоритма KNN для классификации изображений.Он случайным образом делит 1000 изображений в соответствии с соотношением 70% обучающего набора и 30% тестового набора, а затем получает пиксельную гистограмму каждого изображения, согласно к характерному распределению пикселей Выполните анализ классификации изображений. Основной код KNeighborsClassifier() выглядит следующим образом:
- from sklearn.neighbors import KNeighborsClassifier
- clf = KNeighborsClassifier(n_neighbors=11).fit(XX_train, y_train)
- predictions_labels = clf.predict(XX_test)
Полный код и комментарии выглядят следующим образом:
# -*- coding: utf-8 -*-
import os
import cv2
import numpy as np
from sklearn.cross_validation import train_test_split
from sklearn.metrics import confusion_matrix, classification_report
#----------------------------------------------------------------------------------
# 第一步 切分训练集和测试集
#----------------------------------------------------------------------------------
X = [] #定义图像名称
Y = [] #定义图像分类类标
Z = [] #定义图像像素
for i in range(0, 10):
#遍历文件夹,读取图片
for f in os.listdir("photo/%s" % i):
#获取图像名称
X.append("photo//" +str(i) + "//" + str(f))
#获取图像类标即为文件夹名称
Y.append(i)
X = np.array(X)
Y = np.array(Y)
#随机率为100% 选取其中的30%作为测试集
X_train, X_test, y_train, y_test = train_test_split(X, Y,
test_size=0.3, random_state=1)
print len(X_train), len(X_test), len(y_train), len(y_test)
#----------------------------------------------------------------------------------
# 第二步 图像读取及转换为像素直方图
#----------------------------------------------------------------------------------
#训练集
XX_train = []
for i in X_train:
#读取图像
#print i
image = cv2.imread(i)
#图像像素大小一致
img = cv2.resize(image, (256,256),
interpolation=cv2.INTER_CUBIC)
#计算图像直方图并存储至X数组
hist = cv2.calcHist([img], [0,1], None,
[256,256], [0.0,255.0,0.0,255.0])
XX_train.append(((hist/255).flatten()))
#测试集
XX_test = []
for i in X_test:
#读取图像
#print i
image = cv2.imread(i)
#图像像素大小一致
img = cv2.resize(image, (256,256),
interpolation=cv2.INTER_CUBIC)
#计算图像直方图并存储至X数组
hist = cv2.calcHist([img], [0,1], None,
[256,256], [0.0,255.0,0.0,255.0])
XX_test.append(((hist/255).flatten()))
#----------------------------------------------------------------------------------
# 第三步 基于KNN的图像分类处理
#----------------------------------------------------------------------------------
from sklearn.neighbors import KNeighborsClassifier
clf = KNeighborsClassifier(n_neighbors=11).fit(XX_train, y_train)
predictions_labels = clf.predict(XX_test)
print u'预测结果:'
print predictions_labels
print u'算法评价:'
print (classification_report(y_test, predictions_labels))
#输出前10张图片及预测结果
k = 0
while k<10:
#读取图像
print X_test[k]
image = cv2.imread(X_test[k])
print predictions_labels[k]
#显示图像
cv2.imshow("img", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
k = k + 1
В коде отображаются первые десять изображений набора прогнозов, среди которых на рисунке показано изображение «818.jpg», а результат метки класса его прогноза классификации равен «8», что означает восьмой тип горы. , и результат прогноза правильный.
На рисунке ниже показано изображение «452.jpg», и результат предсказания его классификации равен «4», что означает четвертый тип динозавра, и результат предсказания правильный.
На изображении ниже показано изображение «507.jpg», которое имеет метку класса «7» для предсказания классификации, которое ошибочно предсказано как 7-й тип динозавра, а реальный результат должен быть 5-м типом слона.
Алгоритм KNN используется для экспериментов по классификации изображений.Окончательная точность оценки алгоритма (точность), отзыв (отзыв) и F-оценка (F1-оценка) показаны на рисунке, где средний показатель точности составляет 0,64, средний показатель отзыва составляет 0,55, среднее значение F составляет 0,50, что не очень удовлетворительно. Итак, если для классификации используется сверточная нейронная сеть CNN, можно ли повысить точность, постоянно изучая детали?
3. Tensorflow + Opencv реализует классификацию изображений CNN.
Во-первых, нам нужно установить пакет расширения OpenCV в среде TensorFlow; во-вторых, нам нужно построить нейронную сеть CNN через среду TensorFlow; наконец, нам нужно изучить эксперименты по классификации изображений посредством непрерывного обучения.
1. Установка библиотеки OpenCV
Первый шаг — открыть программу Anaconda, выбрать установленную среду «TensorFlow» и запустить Spyder.
На втором этапе нам нужно установить пакет расширения opencv-python в среде TensorFlow, иначе будет выведена ошибка «ModuleNotFoundError: No module named ‘cv2’». Просто вызовите Anaconda Prompt для установки, как показано на следующем рисунке:
activate tensorflow
pip install opencv-python
Установка прошла успешно, как показано на рисунке ниже.
Однако, поскольку сервер .org anaconda находится за границей, скорость загрузки очень низкая, и возникает ошибка «Anaconda. Ошибка HTTP при попытке получить этот URL-адрес. Ошибки HTTP часто возникают периодически».
- Решение 1. Загрузите с зеркала Университета Цинхуа в Китае
- Решение 2. Загрузите соответствующую версию opencv-python с веб-сайта PYPI, а затем установите файл .whl, загруженный локально. ссылка для скачивания:Ууху. Парикмахерская. UCI. Квота / ~ идти будет немедленно / Пак Ючон…
Так как первый метод оказался неудачным, читателям рекомендуется попробовать второй метод, при этом автор загрузит файл «opencv_python-4.1.2-cp36-cp36m-win_amd64.whl» для вашего непосредственного использования. (4.1.2 представляет собой версию opencv, cp36 представляет собой используемый python3.6 и является 64-разрядным).
Третий шаг — вызвать PIP для установки локального пакета расширения opencv.
activate tensorflow
pip install C:\Users\xiuzhang\Desktop\TensorFlow\opencv_python-4.1.2-cp36-cp36m-win_amd64.whl
Этот метод очень быстрый и рекомендуется для всех. После успешной установки приступим к написанию нашего кода!
2. Чтение изображений папок
Конкретные шаги этой части следующие:
- Определяем функцию read_img(), читаем от "0" до "9" в папке "photo"
- Вызовите функцию cv2.imread(), чтобы перебрать все значения пикселей каждого изображения и передать
cv2.resize() равномерно изменен до размера 32 * 32 - Получите по очереди пиксель изображения, метку класса изображения и имя пути к изображению: fpaths, data, label = read_img(path)
- Произвольно отрегулируйте порядок изображений и разделите набор данных в соответствии с соотношением 2-8, где 80% данных используются для обучения, а 20% данных используются для тестирования.
#---------------------------------第一步 读取图像-----------------------------------
def read_img(path):
cate = [path + x for x in os.listdir(path) if os.path.isdir(path + x)]
imgs = []
labels = []
fpath = []
for idx, folder in enumerate(cate):
# 遍历整个目录判断每个文件是不是符合
for im in glob.glob(folder + '/*.jpg'):
#print('reading the images:%s' % (im))
img = cv2.imread(im) #调用opencv库读取像素点
img = cv2.resize(img, (32, 32)) #图像像素大小一致
imgs.append(img) #图像数据
labels.append(idx) #图像类标
fpath.append(path+im) #图像路径名
#print(path+im, idx)
return np.asarray(fpath, np.string_), np.asarray(imgs, np.float32), np.asarray(labels, np.int32)
# 读取图像
fpaths, data, label = read_img(path)
print(data.shape) # (1000, 256, 256, 3)
# 计算有多少类图片
num_classes = len(set(label))
print(num_classes)
# 生成等差数列随机调整图像顺序
num_example = data.shape[0]
arr = np.arange(num_example)
np.random.shuffle(arr)
data = data[arr]
label = label[arr]
fpaths = fpaths[arr]
# 拆分训练集和测试集 80%训练集 20%测试集
ratio = 0.8
s = np.int(num_example * ratio)
x_train = data[:s]
y_train = label[:s]
fpaths_train = fpaths[:s]
x_val = data[s:]
y_val = label[s:]
fpaths_test = fpaths[s:]
print(len(x_train),len(y_train),len(x_val),len(y_val)) #800 800 200 200
print(y_val)
3. Создайте CNN
Конкретные шаги этой части следующие:
-
Сначала определите заполнитель, который используется для передачи входного значения, xs представляет точку изображения размером 32*32 пикселя и содержит три слоя RGB, поэтому размер устанавливается равным 32 * 32 * 3; ys представляет окончательное прогнозируемое значение. значение метки класса каждого изображения.
-
Вызовите функцию tf.layers.conv2d(), чтобы определить слой свертки, включая 20 ядер свертки, размер ядра свертки равен 5, а функция возбуждения — Relu; вызовите функцию tf.layers.max_pooling2d(), чтобы определить процесс объединения, а размер шага равен 2. Удвойте размер.
-
Затем определите второй сверточный слой и слой пула, теперь есть conv0, pool0 и conv1, pool1.
-
Полносвязный слой определяется функцией tf.layers.dense(), преобразуется в вектор признаков длиной 400 и добавляется DropOut для предотвращения переобучения.
-
Выходной слой — это логиты, включая 10 чисел, а окончательный результат прогнозирования — предсказание_меток, то есть tf.arg_max(логиты, 1).
#--------------------------------Второй шаг — построить нейронную сеть-------- -- ----------------------------------------
Определить заполнитель
xs = tf.placeholder(tf.float32, [None, 32, 32, 3]) #32 на изображение323 балла ys = tf.placeholder(tf.int32, [None]) #1 вывод на выборку
Контейнер для хранения параметров DropOut
drop = tf.placeholder(tf.float32) #0,25 для обучения и 0 для тестирования
Определите сверточный слой conv0
conv0 = tf.layers.conv2d(xs, 20, 5, активация=tf.nn.relu) #20 ядер свертки Размер ядра свертки равен 5 Активация Relu
Определите максимальный слой pool0 pool0
pool0 = tf.layers.max_pooling2d(conv0, [2, 2], [2, 2]) # окно пула 2x2 размер шага 2x2 print("Слой0:\n", conv0, pool0)
Определите сверточный слой conv1
conv1 = tf.layers.conv2d(pool0, 40, 4, активация=tf.nn.relu) #40 ядер свертки Размер ядра свертки равен 4 Активация Relu
Определите максимальный слой pool1 pool1
pool1 = tf.layers.max_pooling2d(conv1, [2, 2], [2, 2]) # окно пула 2x2 размер шага 2x2 print("Слой1:\n", conv1, pool1)
Преобразование 3D-объектов в 1D-векторы
flatten = tf.layers.flatten(pool1)
Полностью связанный слой преобразуется в вектор признаков длиной 400.
fc = tf.layers.dense (выравнивание, 400, активация = tf.nn.relu) печать("Слой2:\n", ФК)
Добавьте DropOut, чтобы предотвратить переоснащение
dropout_fc = tf.layers.dropout(fc, drop)
неактивный выходной слой
logits = tf.layers.dense (dropout_fc, num_classes) print("Вывод:\n", логиты)
определить вывод
predicted_labels = tf.arg_max(logits, 1)
4. Определите функцию потерь и оптимизатор
Потеря определяется перекрестной энтропией, а для глубокого обучения используется оптимизатор AdamOptimizer.Основной код выглядит следующим образом.
Данные горячего типа, также известные как однобитовое действительное кодирование, в основном используют N-битный регистр состояния для кодирования N состояний, каждое состояние имеет свой собственный бит регистра, и только один бит является действительным в любой момент времени. Например, [0 0 0 1 0 0 0 0 0 0…] означает «животное».
# 利用交叉熵定义损失
losses = tf.nn.softmax_cross_entropy_with_logits(
labels = tf.one_hot(ys, num_classes), #将input转化为one-hot类型数据输出
logits = logits)
# 平均损失
mean_loss = tf.reduce_mean(losses)
# 定义优化器 学习效率设置为0.0001
optimizer = tf.train.AdamOptimizer(learning_rate=1e-4).minimize(losses)
5. Обучение модели и прогнозирование
Определите переменную поезда тега, когда она равна True, выполняется операция обучения и модель обучения сохраняется; когда она имеет значение False, выполняется прогнозирование, а набор прогнозов 20 % используется для экспериментов по прогнозированию классификации изображений.
#------------------------------------第四步 模型训练和预测-----------------------------------
# 用于保存和载入模型
saver = tf.train.Saver()
# 训练或预测
train = False
# 模型文件路径
model_path = "model/image_model"
with tf.Session() as sess:
if train:
print("训练模式")
# 训练初始化参数
sess.run(tf.global_variables_initializer())
# 定义输入和Label以填充容器 训练时dropout为0.25
train_feed_dict = {
xs: x_train,
ys: y_train,
drop: 0.25
}
# 训练学习1000次
for step in range(1000):
_, mean_loss_val = sess.run([optimizer, mean_loss], feed_dict=train_feed_dict)
if step % 50 == 0: #每隔50次输出一次结果
print("step = {}\t mean loss = {}".format(step, mean_loss_val))
# 保存模型
saver.save(sess, model_path)
print("训练结束,保存模型到{}".format(model_path))
else:
print("测试模式")
# 测试载入参数
saver.restore(sess, model_path)
print("从{}载入模型".format(model_path))
# label和名称的对照关系
label_name_dict = {
0: "人类",
1: "沙滩",
2: "建筑",
3: "公交",
4: "恐龙",
5: "大象",
6: "花朵",
7: "野马",
8: "雪山",
9: "美食"
}
# 定义输入和Label以填充容器 测试时dropout为0
test_feed_dict = {
xs: x_val,
ys: y_val,
drop: 0
}
# 真实label与模型预测label
predicted_labels_val = sess.run(predicted_labels, feed_dict=test_feed_dict)
for fpath, real_label, predicted_label in zip(fpaths_test, y_val, predicted_labels_val):
# 将label id转换为label名
real_label_name = label_name_dict[real_label]
predicted_label_name = label_name_dict[predicted_label]
print("{}\t{} => {}".format(fpath, real_label_name, predicted_label_name))
# 评价结果
print("正确预测个数:", sum(y_val==predicted_labels_val))
print("准确度为:", 1.0*sum(y_val==predicted_labels_val) / len(y_val))
6. Полный код и экспериментальные результаты
Полный код показан ниже.Вот ссылка на часть кода господина Ван Шие.Настоятельно рекомендуется всем изучить его блог. адрес:blog.csdn.net/wills798
"""
Created on Sun Dec 29 19:21:08 2019
@author: xiuzhang Eastmount CSDN
"""
import os
import glob
import cv2
import numpy as np
import tensorflow as tf
# 定义图片路径
path = 'photo/'
#---------------------------------第一步 读取图像-----------------------------------
def read_img(path):
cate = [path + x for x in os.listdir(path) if os.path.isdir(path + x)]
imgs = []
labels = []
fpath = []
for idx, folder in enumerate(cate):
# 遍历整个目录判断每个文件是不是符合
for im in glob.glob(folder + '/*.jpg'):
#print('reading the images:%s' % (im))
img = cv2.imread(im) #调用opencv库读取像素点
img = cv2.resize(img, (32, 32)) #图像像素大小一致
imgs.append(img) #图像数据
labels.append(idx) #图像类标
fpath.append(path+im) #图像路径名
#print(path+im, idx)
return np.asarray(fpath, np.string_), np.asarray(imgs, np.float32), np.asarray(labels, np.int32)
# 读取图像
fpaths, data, label = read_img(path)
print(data.shape) # (1000, 256, 256, 3)
# 计算有多少类图片
num_classes = len(set(label))
print(num_classes)
# 生成等差数列随机调整图像顺序
num_example = data.shape[0]
arr = np.arange(num_example)
np.random.shuffle(arr)
data = data[arr]
label = label[arr]
fpaths = fpaths[arr]
# 拆分训练集和测试集 80%训练集 20%测试集
ratio = 0.8
s = np.int(num_example * ratio)
x_train = data[:s]
y_train = label[:s]
fpaths_train = fpaths[:s]
x_val = data[s:]
y_val = label[s:]
fpaths_test = fpaths[s:]
print(len(x_train),len(y_train),len(x_val),len(y_val)) #800 800 200 200
print(y_val)
#---------------------------------第二步 建立神经网络-----------------------------------
# 定义Placeholder
xs = tf.placeholder(tf.float32, [None, 32, 32, 3]) #每张图片32*32*3个点
ys = tf.placeholder(tf.int32, [None]) #每个样本有1个输出
# 存放DropOut参数的容器
drop = tf.placeholder(tf.float32) #训练时为0.25 测试时为0
# 定义卷积层 conv0
conv0 = tf.layers.conv2d(xs, 20, 5, activation=tf.nn.relu) #20个卷积核 卷积核大小为5 Relu激活
# 定义max-pooling层 pool0
pool0 = tf.layers.max_pooling2d(conv0, [2, 2], [2, 2]) #pooling窗口为2x2 步长为2x2
print("Layer0:\n", conv0, pool0)
# 定义卷积层 conv1
conv1 = tf.layers.conv2d(pool0, 40, 4, activation=tf.nn.relu) #40个卷积核 卷积核大小为4 Relu激活
# 定义max-pooling层 pool1
pool1 = tf.layers.max_pooling2d(conv1, [2, 2], [2, 2]) #pooling窗口为2x2 步长为2x2
print("Layer1:\n", conv1, pool1)
# 将3维特征转换为1维向量
flatten = tf.layers.flatten(pool1)
# 全连接层 转换为长度为400的特征向量
fc = tf.layers.dense(flatten, 400, activation=tf.nn.relu)
print("Layer2:\n", fc)
# 加上DropOut防止过拟合
dropout_fc = tf.layers.dropout(fc, drop)
# 未激活的输出层
logits = tf.layers.dense(dropout_fc, num_classes)
print("Output:\n", logits)
# 定义输出结果
predicted_labels = tf.arg_max(logits, 1)
#---------------------------------第三步 定义损失函数和优化器---------------------------------
# 利用交叉熵定义损失
losses = tf.nn.softmax_cross_entropy_with_logits(
labels = tf.one_hot(ys, num_classes), #将input转化为one-hot类型数据输出
logits = logits)
# 平均损失
mean_loss = tf.reduce_mean(losses)
# 定义优化器 学习效率设置为0.0001
optimizer = tf.train.AdamOptimizer(learning_rate=1e-4).minimize(losses)
#------------------------------------第四步 模型训练和预测-----------------------------------
# 用于保存和载入模型
saver = tf.train.Saver()
# 训练或预测
train = False
# 模型文件路径
model_path = "model/image_model"
with tf.Session() as sess:
if train:
print("训练模式")
# 训练初始化参数
sess.run(tf.global_variables_initializer())
# 定义输入和Label以填充容器 训练时dropout为0.25
train_feed_dict = {
xs: x_train,
ys: y_train,
drop: 0.25
}
# 训练学习1000次
for step in range(1000):
_, mean_loss_val = sess.run([optimizer, mean_loss], feed_dict=train_feed_dict)
if step % 50 == 0: #每隔50次输出一次结果
print("step = {}\t mean loss = {}".format(step, mean_loss_val))
# 保存模型
saver.save(sess, model_path)
print("训练结束,保存模型到{}".format(model_path))
else:
print("测试模式")
# 测试载入参数
saver.restore(sess, model_path)
print("从{}载入模型".format(model_path))
# label和名称的对照关系
label_name_dict = {
0: "人类",
1: "沙滩",
2: "建筑",
3: "公交",
4: "恐龙",
5: "大象",
6: "花朵",
7: "野马",
8: "雪山",
9: "美食"
}
# 定义输入和Label以填充容器 测试时dropout为0
test_feed_dict = {
xs: x_val,
ys: y_val,
drop: 0
}
# 真实label与模型预测label
predicted_labels_val = sess.run(predicted_labels, feed_dict=test_feed_dict)
for fpath, real_label, predicted_label in zip(fpaths_test, y_val, predicted_labels_val):
# 将label id转换为label名
real_label_name = label_name_dict[real_label]
predicted_label_name = label_name_dict[predicted_label]
print("{}\t{} => {}".format(fpath, real_label_name, predicted_label_name))
# 评价结果
print("正确预测个数:", sum(y_val==predicted_labels_val))
print("准确度为:", 1.0*sum(y_val==predicted_labels_val) / len(y_val))
Результат обучения следующий:
(1000, 32, 32, 3)
10
800 800 200 200
[2 8 6 9 9 5 2 2 9 3 7 0 6 0 0 1 3 2 7 3 4 6 9 5 8 6 4 1 1 4 4 8 6 2 6 1 2
5 0 7 9 5 2 4 6 8 7 5 8 1 6 5 1 4 8 1 9 1 8 8 6 1 0 5 3 3 1 2 9 1 8 7 6 0
8 1 8 0 2 1 3 5 3 6 9 8 7 5 2 5 2 8 8 8 4 2 2 4 3 5 3 3 9 1 1 5 2 6 7 6 7
0 7 4 1 7 2 9 4 0 3 8 7 5 3 8 1 9 3 6 8 0 0 1 7 7 9 5 4 0 3 0 4 5 7 2 2 3
0 8 2 0 2 3 5 1 7 2 1 6 5 8 1 4 6 6 8 6 5 5 1 7 2 8 7 1 3 9 7 1 3 6 0 8 7
5 8 0 1 2 7 9 6 2 4 7 7 2 8 0]
Layer0:
Tensor("conv2d_1/Relu:0", shape=(?, 28, 28, 20), dtype=float32)
Tensor("max_pooling2d_1/MaxPool:0", shape=(?, 14, 14, 20), dtype=float32)
Layer1:
Tensor("conv2d_2/Relu:0", shape=(?, 11, 11, 40), dtype=float32)
Tensor("max_pooling2d_2/MaxPool:0", shape=(?, 5, 5, 40), dtype=float32)
Layer2:
Tensor("dense_1/Relu:0", shape=(?, 400), dtype=float32)
Output:
Tensor("dense_2/BiasAdd:0", shape=(?, 10), dtype=float32)
训练模式
step = 0 mean loss = 66.93688201904297
step = 50 mean loss = 3.376957654953003
step = 100 mean loss = 0.5910811424255371
step = 150 mean loss = 0.061084795743227005
step = 200 mean loss = 0.013018212281167507
step = 250 mean loss = 0.006795921362936497
step = 300 mean loss = 0.004505819175392389
step = 350 mean loss = 0.0032660639844834805
step = 400 mean loss = 0.0024683878291398287
step = 450 mean loss = 0.0019308131886646152
step = 500 mean loss = 0.001541870180517435
step = 550 mean loss = 0.0012695763725787401
step = 600 mean loss = 0.0010685999877750874
step = 650 mean loss = 0.0009132082923315465
step = 700 mean loss = 0.0007910516578704119
step = 750 mean loss = 0.0006900889566168189
step = 800 mean loss = 0.0006068988586775959
step = 850 mean loss = 0.0005381597438827157
step = 900 mean loss = 0.0004809059901162982
step = 950 mean loss = 0.0004320790758356452
训练结束,保存模型到model/image_model
Прогнозируемые выходные результаты показаны на рисунке ниже.Окончательный прогноз верен для 181 изображения, а точность составляет 0,905. По сравнению с предыдущим машинным обучением KNN 0,500, это очень большое улучшение.
测试模式
INFO:tensorflow:Restoring parameters from model/image_model
从model/image_model载入模型
b'photo/photo/3\\335.jpg' 公交 => 公交
b'photo/photo/1\\129.jpg' 沙滩 => 沙滩
b'photo/photo/7\\740.jpg' 野马 => 野马
b'photo/photo/5\\564.jpg' 大象 => 大象
...
b'photo/photo/9\\974.jpg' 美食 => 美食
b'photo/photo/2\\220.jpg' 建筑 => 公交
b'photo/photo/9\\912.jpg' 美食 => 美食
b'photo/photo/4\\459.jpg' 恐龙 => 恐龙
b'photo/photo/5\\525.jpg' 大象 => 大象
b'photo/photo/0\\44.jpg' 人类 => 人类
正确预测个数: 181
准确度为: 0.905
4. Резюме
На данный момент эта статья закончена, и будут продолжать публиковаться другие статьи о глубоком обучении TensorFlow.В то же время будут подробно объясняться экспериментальная оценка, RNN, LSTM и различные профессиональные случаи. Наконец, я надеюсь, что эта базовая статья будет вам полезна.Если в статье есть ошибки или недостатки, пожалуйста, также спросите у Haihan~ Как новичок в области искусственного интеллекта, я надеюсь, что смогу продолжать улучшать и углублять, а затем применять его к распознавание изображений, сетевая безопасность, враждебные образцы и другие области, помогите всем написать простые академические статьи, давай вместе!
использованная литература:
[1] Гонсалес, Цифровая обработка изображений (3-е издание) [M], Пекин: Electronic Industry Press, 2013.
[2] Ян Сючжан, Ян На. Сканирование и анализ сетевых данных Python от входа до освоения (анализ) [M].Пекин: Пекинский университет аэронавтики и астронавтики, 2018.
[3] Луо Цзицзян и др. Обработка изображений в Python [M], Science Press, 2020.
[4] [курс интеллектуального анализа данных python] 20. Анализ алгоритма классификации ближайшего соседа KNN, подробный анализ и сбалансированная шкала чтения набора данных TXT
[5] TensorFlow [Минималистский] CNN — Бог Yellow_python
[6] Локализация источника звука на основе направленной активации глубокой нейронной сети для получения информации о фазе - Чжан Цзыю Кевин
[7] TensorFlow в действии: глава 5 (классическая сверточная нейронная сеть CNN-3 (GoogleNet)) - DFann
[8] GitHub.com/FourUCApress/CNN…
[9] Объяснение обработки изображений — пример использования CNN для классификации изображений — Bingjiling
[10] Классификация дефектов изображения на основе CNN — BellaVita1
[12] Обучение tensorflow (шесть) для классификации ваших собственных изображений (сверхдетальная входная версия CNN)
[13] Объясните, как тензорный поток обучает ваш собственный набор данных для реализации классификации изображений CNN — Ван Шие (сильный толчок)
[14] GitHub.com/Hu Jun Прецедент…
[15] тензорный поток (3): классификация изображений с помощью CNN — поток
[16] Вводное руководство по распознаванию изображений TensorFlow (классификация объектов) — cococok2
[17] GitHub.com/Wipe LSS ion/F U…
[18] Классификация изображений CNN - Fire Dance_Quicksand
[19] Однокомпонентная классификация изображений CNN (базовая сеть VGG16 на основе TensorFlow)
[20] GitHub.com/FourUCApress/CNN…
[21] Tensorflow реализует CNN для распознавания MNIST — siucaan (сильный толчок)
[22] Установите tensorflow, opencv с помощью Anaconda3, чтобы он мог работать в spyder.
Нажмите «Подписаться», чтобы впервые узнать о новых технологиях HUAWEI CLOUD~