# 使用tensorflow搭建分类神经网络以及迁移学习（训练过程）

———Start

###### 本文不涉及tensorflow环境配置过程，只讲解整个项目代码大致内容。至于每个函数的每个参数意义，同学们可以百度了解或私信我，见谅！

[En]

The first part (Custom Model structure)

Normal类

Tuberculosis类

### ; 1、项目结构

train.py：训练文件
test.py：测试文件
class_indices.json 类别信息文件(训练网络时自动生成)
our_model.py 模型文件
weights：权重文件（训练完毕之后，自动生成权重文件）

### 2、train.py

#### 2.3 声明训练集和验证集数据增强器

[En]

The function of the intensifier is to preprocess the data (normalization, flipping, rotation, etc.)

#### ; 2.4 根据增强器生成打包后的数据

[En]

Apply an intensifier to the image data in the dataset to generate data in the format required by the network

#### 2.7 训练一次模型的函数

[En]

The execution process is as follows: training the model once, calculating the loss, calculating and updating the gradient, and calculating the accuracy.

#### ; 2.8 验证一次模型的函数

[En]

The execution process is as follows: the model is verified after one round of training, the loss is calculated and the accuracy is calculated. The validation process does not update the gradient.

#### 2.11 记录精度和损失并保存权重

[En]

After the verification is completed, the accuracy and loss of the training and verification process are recorded, and the model weight is saved.

#### ; 2.12 模型训练成功

[En]

If the following effects occur, the model training is successful.

#### 2.13 全部代码（our_model.py）

from tensorflow.keras import layers,Model

def get_model():

input_image = layers.Input(shape=(128, 128, 3), dtype="float32")

x = layers.Conv2D(filters=16, kernel_size=3, strides=2,use_bias=False)(input_image)

x = layers.BatchNormalization(momentum=0.9, epsilon=1e-5)(x)

x = layers.ReLU()(x)

x = layers.Conv2D(32, kernel_size=3, strides=2,use_bias=False)(x)
x = layers.BatchNormalization(momentum=0.9, epsilon=1e-5)(x)
x = layers.ReLU()(x)

x = layers.Conv2D(64, kernel_size=3, strides=2,use_bias=False)(x)
x = layers.BatchNormalization(momentum=0.9, epsilon=1e-5)(x)
x = layers.ReLU()(x)

x = layers.Conv2D(128, kernel_size=3, strides=2,use_bias=False)(x)
x = layers.BatchNormalization(momentum=0.9, epsilon=1e-5)(x)
x = layers.ReLU()(x)

x = layers.Conv2D(256, kernel_size=3, strides=2,use_bias=False)(x)
x = layers.BatchNormalization(momentum=0.9, epsilon=1e-5)(x)
x = layers.ReLU()(x)

x = layers.Conv2D(256, kernel_size=3, strides=2,use_bias=False)(x)
x = layers.BatchNormalization(momentum=0.9, epsilon=1e-5)(x)
x = layers.ReLU()(x)
x = layers.GlobalAvgPool2D(name="avgPool")(x)

x = layers.Dropout(rate=0.5)(x)

x= layers.Dense(units=100,activation="relu")(x)

x= layers.Dropout(rate=0.5)(x)
x = layers.Dense(2, name="logits")(x)

predict = layers.Softmax()(x)

model = Model(inputs=input_image, outputs=predict,name='tb_model')
return model



#### 2.14 全部代码（train.py）

import os

import json
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tqdm import tqdm
from train_models import our_model

def main():

image_path = "G:\dataset\TB_Database22"

train_dir = os.path.join(image_path, "train")

validation_dir = os.path.join(image_path, "test")

weight_path = "weights"
assert os.path.exists(weight_path), "cannot find {}".format(weight_path)
assert os.path.exists(train_dir), "cannot find {}".format(train_dir)
assert os.path.exists(validation_dir), "cannot find {}".format(validation_dir)

im_height = 256
im_width = 256

batch_size = 4

epochs = 2

lr = 0.001

train_image_generator = ImageDataGenerator(horizontal_flip=True,
rescale=1./255,
vertical_flip=True,
rotation_range=6,
brightness_range=[0.1,2])

validation_image_generator = ImageDataGenerator(rescale=1./255)

train_data_gen = train_image_generator.flow_from_directory(directory=train_dir,
batch_size=batch_size,
shuffle=True,
target_size=(im_height, im_width),
class_mode='categorical')

val_data_gen = validation_image_generator.flow_from_directory(directory=validation_dir,
batch_size=batch_size,
shuffle=True,
target_size=(im_height, im_width),
class_mode='categorical')

total_train = train_data_gen.n

total_val = val_data_gen.n

class_indices = train_data_gen.class_indices

inverse_dict = dict((val, key) for key, val in class_indices.items())

json_str = json.dumps(inverse_dict, indent=4)
with open('class_indices.json', 'w') as json_file:
json_file.write(json_str)

print("using {} images for training, {} images for validation.".format(total_train,
total_val))

model = our_model.get_model()

model.summary()

loss_object = tf.keras.losses.CategoricalCrossentropy(from_logits=False)

optimizer = tf.keras.optimizers.SGD(learning_rate=lr,momentum=0.9)

train_loss = tf.keras.metrics.Mean(name='train_loss')

train_accuracy = tf.keras.metrics.CategoricalAccuracy(name='train_accuracy')

val_loss = tf.keras.metrics.Mean(name='val_loss')

val_accuracy = tf.keras.metrics.CategoricalAccuracy(name='val_accuracy')

@tf.function
def train_step(images, labels):

output = model(images, training=True)

loss = loss_object(labels,output)

train_loss(loss)

train_accuracy(labels, output)

@tf.function
def val_step(images, labels):
output = model(images, training=False)
loss = loss_object(labels, output)
val_loss(loss)
val_accuracy(labels, output)

best_val_acc = 0.

trainloss=[]
trainaccuracy = []
valloss=[]
valaccuracy = []

for epoch in range(epochs):
train_loss.reset_states()
train_accuracy.reset_states()
val_loss.reset_states()
val_accuracy.reset_states()

count = range(total_train // batch_size)
train_bar = tqdm(count)
for step in train_bar:

images, labels = next(train_data_gen)
train_step(images, labels)

train_bar.desc = "train epoch[{}/{}] loss:{:.3f}, acc:{:.3f}".format(epoch + 1,
epochs,
train_loss.result(),
train_accuracy.result())

val_bar = tqdm(range(total_val // batch_size))
for step in val_bar:
test_images, test_labels = next(val_data_gen)
val_step(test_images, test_labels)

val_bar.desc = "valid epoch[{}/{}] loss:{:.3f}, acc:{:.3f}".format(epoch + 1,
epochs,
val_loss.result(),
val_accuracy.result())

trainloss.append(train_loss.result().numpy())
trainaccuracy.append(train_accuracy.result().numpy())
valloss.append(val_loss.result().numpy())
valaccuracy.append(val_accuracy.result().numpy())

if val_accuracy.result() > best_val_acc:
best_val_acc = val_accuracy.result()
model.save_weights(weight_path+"\epoch{}-acc{:.3f}-loss{:.3f}_newModel.ckpt".format(
epoch,val_accuracy.result(),val_loss.result()
),save_format='tf')

print("trainloss:{}".format(trainloss))
print("trainaccuracy:{}".format(trainaccuracy))
print("valloss:{}".format(valloss))
print("valaccuracy:{}".format(valaccuracy))
if __name__ == '__main__':
main()



#### 2.15 全部代码（test.py）

import glob
from time import time

import numpy as np
import os
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve, auc
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tqdm import tqdm
import tensorflow as tf
from train_models.our_model import get_model
from tool import genConfusionMatrix
from tool import roc_auc

rootpath=r"G:\dataset\TB_Database22\test"
assert os.path.exists(rootpath), "cannot find {}".format(rootpath)
tf.compat.v1.enable_eager_execution(
config=None,
device_policy=None,
execution_mode=None
)

im_height = 224
im_width = 224
batch_size = 2

model =get_model()
weights_path = r'./weights/epoch0-acc0.500-loss0.717_newModel.ckpt'
assert len(glob.glob(weights_path + "*")), "cannot find {}".format(weights_path)

test_image_generator = ImageDataGenerator(rescale=1./255)

test_data_gen = test_image_generator.flow_from_directory(directory=rootpath,
target_size=(im_height,im_width),
batch_size=batch_size,
class_mode='sparse',
shuffle=False)

total_test = test_data_gen.n

val_bar = tqdm(range(total_test // batch_size))

result = np.array([],dtype=int)

label = np.array([],dtype=int)

times = 0.0

for step in val_bar:

test_images, test_labels = next(test_data_gen)
start = time()

data_numpy = model(test_images, training=False)

times+=(time()-start)

data_numpy = data_numpy.numpy()

result = np.append(result,data_numpy.argmax(axis=1))

label = np.append(label,test_labels)

end = time()

print("耗费时间:",times/total_test)

label = label.astype(np.int8)
matrix = genConfusionMatrix(2,result,label)
matrix_se = matrix[1][1]/(matrix[1][0]+matrix[1][1])
matrix_sp = matrix[0][0]/(matrix[0][1]+matrix[0][0])
matrix_acc = (matrix[0][0]+matrix[1][1])/np.sum(matrix)
matrix_auc = roc_auc(label,result)
matrix_pre = matrix[1][1]/(matrix[0][1]+matrix[1][1])
matrix_youden = matrix_se+matrix_sp-1
print("混淆矩阵：")
print(matrix)
print("matrix_se",matrix_se)
print("matrix_sp",matrix_sp)
print("matrix_auc",matrix_auc)
print("matrix_acc",matrix_acc)
print("matric_pre",matrix_pre)
print("约登指数",matrix_youden)
print("weights_path:", weights_path)



#### 使用MobileNetV2实现迁移学习

def get_MobileNetV2():
feature = MobileNetV2(input_shape=(224,224,3),include_top=False,weights='imagenet')

feature.trainable=False
model = Sequential([
feature,
layers.GlobalAveragePooling2D(),
layers.Dense(1000, activation='relu'),
layers.Dense(1000, activation='relu'),
layers.Dense(2,activation='relu')
layers.Softmax()
],name='MobileNetV2')
return model


from tensorflow.keras.applications import MobileNetV2,NASNetMobile,InceptionV3,ResNet50



model = get_MobileNetV2()


tensorflow.keras提供了很多官方网路结构，通过语句from tensorflow.keras.applications import 模型名称 可以直接使用，初次调用模型时会自动联网下载好权重，再次调用模型时则不需要联网。在此，我将自己的our_model.py放在文末，需要的小伙伴可以直接拿去用哦。

from tensorflow.keras import layers,Model,Sequential
from tensorflow.keras.applications import MobileNetV2,NASNetMobile,InceptionV3,ResNet50,VGG16,ResNet101,DenseNet121

def get_model():

input_image = layers.Input(shape=(128, 128, 3), dtype="float32")

x = layers.Conv2D(filters=16, kernel_size=3, strides=2,use_bias=False)(input_image)

x = layers.BatchNormalization(momentum=0.9, epsilon=1e-5)(x)

x = layers.ReLU()(x)

x = layers.Conv2D(32, kernel_size=3, strides=2,use_bias=False)(x)
x = layers.BatchNormalization(momentum=0.9, epsilon=1e-5)(x)
x = layers.ReLU()(x)

x = layers.Conv2D(64, kernel_size=3, strides=2,use_bias=False)(x)
x = layers.BatchNormalization(momentum=0.9, epsilon=1e-5)(x)
x = layers.ReLU()(x)

x = layers.Conv2D(128, kernel_size=3, strides=2,use_bias=False)(x)
x = layers.BatchNormalization(momentum=0.9, epsilon=1e-5)(x)
x = layers.ReLU()(x)

x = layers.Conv2D(256, kernel_size=3, strides=2,use_bias=False)(x)
x = layers.BatchNormalization(momentum=0.9, epsilon=1e-5)(x)
x = layers.ReLU()(x)

x = layers.Conv2D(256, kernel_size=3, strides=2,use_bias=False)(x)
x = layers.BatchNormalization(momentum=0.9, epsilon=1e-5)(x)
x = layers.ReLU()(x)
x = layers.GlobalAvgPool2D(name="avgPool")(x)

x = layers.Dropout(rate=0.5)(x)

x= layers.Dense(units=100,activation="relu")(x)

x= layers.Dropout(rate=0.5)(x)
x = layers.Dense(2, name="logits")(x)

predict = layers.Softmax()(x)

model = Model(inputs=input_image, outputs=predict,name='tb_model')
return model

def get_MobileNetV2():
feature = MobileNetV2(input_shape=(224,224,3),include_top=False,weights='imagenet')
feature.trainable=False
model = Sequential([
feature,
layers.GlobalAveragePooling2D(),
layers.Dense(1000,activation='relu'),
layers.Dense(1000, activation='relu'),
layers.Dense(2),
layers.Softmax()
],name='MobileNetV2')

return model

def get_NASNetMobile():
feature = NASNetMobile(input_shape=(224,224,3),include_top=False,weights='imagenet')
model = Sequential([
feature,
layers.GlobalAveragePooling2D(),
layers.Dense(1000, activation='relu'),
layers.Dense(1000, activation='relu'),
layers.Dense(2),
layers.Softmax()
],name='NASNetMobile')
return model

def get_InceptionV3():
feature = InceptionV3(input_shape=(299,299,3),include_top=False,weights='imagenet')
model = Sequential([
feature,
layers.GlobalAveragePooling2D(),
layers.Dense(1000, activation='relu'),
layers.Dense(1000, activation='relu'),
layers.Dense(2),
layers.Softmax()
],name='NASNetMobile')
return model

def get_ResNet50():
feature = ResNet50(input_shape=(224, 224, 3), include_top=False, weights='imagenet')
feature.trainable=False
model = Sequential([
feature,
layers.GlobalAveragePooling2D(),
layers.Dense(1000, activation='relu'),
layers.Dense(1000, activation='relu'),
layers.Dense(2),
layers.Softmax()
],name='ResNet50')

return model

def get_vgg16():
feature = VGG16(input_shape=(224,224,3),include_top=False, weights='imagenet')
feature.trainable=False

model = Sequential([
feature,
layers.Flatten(),
layers.Dense(1000, activation='relu'),
layers.Dense(1000, activation='relu'),
layers.Dense(2, activation='softmax')
],name='Vgg16')
return model

def get_ResNet101():
feature = ResNet101(input_shape=(224, 224, 3), include_top=False, weights='imagenet')
feature.trainable=False
model = Sequential([
feature,
layers.GlobalAveragePooling2D(),
layers.Dense(1000, activation='relu'),
layers.Dense(1000, activation='relu'),
layers.Dense(2),
layers.Softmax()
],name='ResNet101')

return model

def get_DenseNet121():
feature = DenseNet121(input_shape=(224, 224, 3), include_top=False, weights='imagenet')
feature.trainable=False
model = Sequential([
feature,
layers.GlobalAveragePooling2D(),
layers.Dense(1000, activation='relu'),
layers.Dense(1000, activation='relu'),
layers.Dense(2),
layers.Softmax()
],name='ResNet101')

return model



Original: https://blog.csdn.net/qq_37652891/article/details/124136862
Author: 小小小MaYi
Title: 使用tensorflow搭建分类神经网络以及迁移学习（训练过程）

(0)

### 大家都在看

• #### 关于相似度计算方法的python实现

关于相似度计算方法的python实现 欧氏距离，曼哈顿距离：计算两个向量间的相似程度，值越小，相似度越高高斯距离（标准化欧氏距离）：计算两个向量间的相似程度，值越大，相似度越高余弦…

人工智能 2023年5月31日
0156
• #### TensorFlow构建模型二

人工智能 2023年5月26日
0111
• #### MECT: Multi-Metadata Embedding based Cross-Transformer forChinese Named Entity Recognition论文实验复现记录

萌新第一次复现实验，做得磕磕绊绊的，简单记录一下 也感谢zsh2517和yyc489的帮助！！ 论文链接：https://arxiv.org/pdf/2104.07204.pdf …

人工智能 2023年5月28日
0140
• #### Blenderpro虚拟数据集的生成

Blenderpro虚拟数据集的生成 简介 Blenderproc的安装环境配置 ……………………

人工智能 2023年7月10日
0141
• #### 【Swin Transformer】Win10使用Swin Transformer做目标检测 (使用自己的数据集 + 图解超详细)

文章目录 Swin Transformer * 环境搭建 – VS2019配置 conda虚拟环境 Pytorch安装 mmcv安装 + 查看匹配版本 安装mmcv m…

人工智能 2023年7月21日
0206
• #### 分类与预测——回归分析

文章目录 分类与预测—回归分析 * 一、回归分析 – 线性回归 逻辑斯蒂回归 分类与预测—回归分析 一、回归分析 回归分析：是一种通过建立模型来研究变量之间相互关系的一…

人工智能 2023年7月3日
0160
• #### javaweb JSP JAVA 电影院在线订票系统（电影购票系统 电影售票 电影票预订系统）（支持在线选座）

JSP电影院在线订票系统（电影购票系统 电影售票 电影票预订系统）（支持在线选座） Original: https://blog.csdn.net/m0_69711799/arti…

人工智能 2023年6月30日
0117
• #### Pytorch —-注意力机制与自注意力机制的代码详解与使用

注意力机制的核心重点就是让网络关注到它更需要关注的地方。 当我们使用卷积神经网络去处理图片的时候， 我们会更希望卷积神经网络去注意应该注意的地方，而不是什么都关注 ，我们不可能手动…

人工智能 2023年6月22日
0172
• #### 机器学习——支持向量机

支持向量机简述 线性可分支持向量机 * 泛化性 基本思想 间隔与向量机 软间隔最大化 非线性支持向量机 序列最小优化算法 线性可分支持向量机 泛化性 先来了解一下什么叫泛化性？我们…

人工智能 2023年7月3日
0170
• #### 【编程题】【Scratch三级】2021.12 分身术

分身术 ; 1. 准备工作 （1）删除小猫角色、添加角色”Monkey”，Money位于舞台的中心； （2）添加背景Light； （3）新建变量&#8221…

人工智能 2023年6月30日
0162
• #### FasterRCNN

FasterRCNN 论文：”Faster R-CNN: Towards Real-Time Object Detection with Region Proposal…

人工智能 2023年7月12日
0110
• #### 200道Java面试题整理，掌握这些还怕面试官？

CSDN话题挑战赛第2期参赛话题：学习笔记 目录 面向对象 JDK JRE JVM 线程、并发相关 spring springmvc、springBoot Mybatis Mysq…

人工智能 2023年6月21日
0137
• #### 聚类轮廓系数java_轮廓系数的应用：kmeans聚类理论篇K的选择（轮廓系数）

前言javascript kmeans是最简单的聚类算法之一，可是运用十分普遍。最近在工做中也常常遇到这个算法。kmeans通常在数据分析前期使用，选取适当的k，将数据分类后，而后…

人工智能 2023年6月2日
0164
• #### Java图片或视频生成GIF动图，发送微信

目录 前言 GIF简介 代码生成 * 图片合成GIF 自定义GIF动图 视频生成GIF 发送微信 小结 前言 别人的博客文章中有动态显示这是怎么做到的呢？别人的微信发送的表情动态为…

人工智能 2023年6月21日
0115
• #### 难受啊，139天备战字节跳动，一个疏忽让我前功尽弃…

面试是走的内推途径，因为内推的简历通过率远高于其他方式;我的内推的途径有：联系我在字节跳动工作的一个大学学长。 在线面试，有个线上文本编辑器，类似leetcode那种，可以在线编程…

人工智能 2023年7月30日
0139
• #### np.linalg.norm()用法总结

前言 np.linalg.norm()用于求范数，linalg本意为linear(线性) + algebra(代数)，norm则表示范数。 用法 np.linalg.norm(x,…

人工智能 2023年6月13日
0136