活动地址:CSDN21天学习挑战赛
目录
tensorflow零基础入门学习_重邮研究森的博客-CSDN博客_tensorflow 学习https://blog.csdn.net/m0_60524373/article/details/124143223>- 本文为[365天深度学习训练营](https://mp.weixin.qq.com/s/k-vYaC8l7uxX51WoypLkTw) 中的学习记录博客
>- 参考文章地址:(深度学习100例 | 第26天-卷积神经网络(CNN):乳腺癌识别_K同学啊的博客-CSDN博客)
本文开发环境:tensorflowgpu2.5
我这个人对于任何代码,我都会先去跑通之和才会去观看内容,哈哈哈,所以第一步我们先不管37=21,直接把博主的代码复制黏贴一份运行结果。(PS:做了一些修改,因为原文是jupyter,而我在pycharm)
- import tensorflow as tf
-
- gpus = tf.config.list_physical_devices("GPU")
-
- if gpus:
- gpu0 = gpus[0] # 如果有多个GPU,仅使用第0个GPU
- tf.config.experimental.set_memory_growth(gpu0, True) # 设置GPU显存用量按需使用
- tf.config.set_visible_devices([gpu0], "GPU")
-
- import matplotlib.pyplot as plt
- import os, PIL, pathlib
- import numpy as np
- import pandas as pd
- import warnings
- from tensorflow import keras
-
- warnings.filterwarnings("ignore") # 忽略警告信息
- plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
- plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
-
- import pathlib
-
- data_dir = "./data"
- data_dir = pathlib.Path(data_dir)
- image_count = len(list(data_dir.glob('*/*')))
- print("图片总数为:",image_count)
-
- batch_size = 16
- img_height = 50
- img_width = 50
-
- """
- 关于image_dataset_from_directory()的详细介绍可以参考文章:https://mtyjkh.blog.csdn.net/article/details/117018789
- """
- train_ds = tf.keras.preprocessing.image_dataset_from_directory(
- data_dir,
- validation_split=0.2,
- subset="training",
- seed=12,
- image_size=(img_height, img_width),
- batch_size=batch_size)
-
- """
- 关于image_dataset_from_directory()的详细介绍可以参考文章:https://mtyjkh.blog.csdn.net/article/details/117018789
- """
- val_ds = tf.keras.preprocessing.image_dataset_from_directory(
- data_dir,
- validation_split=0.2,
- subset="validation",
- seed=12,
- image_size=(img_height, img_width),
- batch_size=batch_size)
-
- class_names = train_ds.class_names
- print(class_names)
-
- for image_batch, labels_batch in train_ds:
- print(image_batch.shape)
- print(labels_batch.shape)
- break
-
- AUTOTUNE = tf.data.AUTOTUNE
-
- def train_preprocessing(image,label):
- return (image/255.0,label)
-
- train_ds = (
- train_ds.cache()
- .shuffle(1000)
- .map(train_preprocessing) # 这里可以设置预处理函数
- # .batch(batch_size) # 在image_dataset_from_directory处已经设置了batch_size
- .prefetch(buffer_size=AUTOTUNE)
- )
-
- val_ds = (
- val_ds.cache()
- .shuffle(1000)
- .map(train_preprocessing) # 这里可以设置预处理函数
- # .batch(batch_size) # 在image_dataset_from_directory处已经设置了batch_size
- .prefetch(buffer_size=AUTOTUNE)
- )
-
- plt.figure(figsize=(10, 8)) # 图形的宽为10高为5
- plt.suptitle("数据展示")
-
- class_names = ["乳腺癌细胞","正常细胞"]
-
- # for images, labels in train_ds.take(1):
- # for i in range(15):
- # plt.subplot(4, 5, i + 1)
- # plt.xticks([])
- # plt.yticks([])
- # plt.grid(False)
- #
- # # 显示图片
- # plt.imshow(images[i])
- # # 显示标签
- # plt.xlabel(class_names[labels[i]-1])
- #
- # plt.show()
-
- import tensorflow as tf
-
- model = tf.keras.Sequential([
- tf.keras.layers.Conv2D(filters=16,kernel_size=(3,3),padding="same",activation="relu",input_shape=[img_width, img_height, 3]),
- tf.keras.layers.Conv2D(filters=16,kernel_size=(3,3),padding="same",activation="relu"),
-
- tf.keras.layers.MaxPooling2D((2,2)),
- tf.keras.layers.Dropout(0.5),
- tf.keras.layers.Conv2D(filters=16,kernel_size=(3,3),padding="same",activation="relu"),
- tf.keras.layers.MaxPooling2D((2,2)),
- tf.keras.layers.Conv2D(filters=16,kernel_size=(3,3),padding="same",activation="relu"),
- tf.keras.layers.MaxPooling2D((2,2)),
- tf.keras.layers.Flatten(),
- tf.keras.layers.Dense(2, activation="softmax")
- ])
- model.summary()
-
- model.compile(optimizer="adam",
- loss='sparse_categorical_crossentropy',
- metrics=['accuracy'])
- from tensorflow.keras.callbacks import ModelCheckpoint, Callback, EarlyStopping, ReduceLROnPlateau, LearningRateScheduler
-
- NO_EPOCHS = 100
- PATIENCE = 5
- VERBOSE = 1
-
- # 设置动态学习率
- annealer = LearningRateScheduler(lambda x: 1e-3 * 0.99 ** (x+NO_EPOCHS))
-
- # 设置早停
- earlystopper = EarlyStopping(monitor='loss', patience=PATIENCE, verbose=VERBOSE)
-
- #
- checkpointer = ModelCheckpoint('best_model.h5',
- monitor='val_accuracy',
- verbose=VERBOSE,
- save_best_only=True,
- save_weights_only=True)
- train_model = model.fit(train_ds,
- epochs=NO_EPOCHS,
- verbose=1,
- validation_data=val_ds,
- callbacks=[earlystopper, checkpointer, annealer])
-
- acc = train_model.history['accuracy']
- val_acc = train_model.history['val_accuracy']
-
- loss = train_model.history['loss']
- val_loss = train_model.history['val_loss']
-
- epochs_range = range(len(acc))
-
- plt.figure(figsize=(12, 4))
- plt.subplot(1, 2, 1)
-
- plt.plot(epochs_range, acc, label='Training Accuracy')
- plt.plot(epochs_range, val_acc, label='Validation Accuracy')
- plt.legend(loc='lower right')
- plt.title('Training and Validation Accuracy')
-
- plt.subplot(1, 2, 2)
- plt.plot(epochs_range, loss, label='Training Loss')
- plt.plot(epochs_range, val_loss, label='Validation Loss')
- plt.legend(loc='upper right')
- plt.title('Training and Validation Loss')
- plt.show()
-
- # 保存模型
- model.save('model/26_model.h5')
点击pycharm即可运行出最后的预测结果!
这里的结果是指网络模型的保存和损失函数这些的输出,对于模型的预测结果我们将在最后显示。
神经网络的整个过程我分为如下六部分,而我们也会对这六部分进行逐部分分析。那么这6部分分别是:
六步法:
1->import
2->train test(指定训练集的输入特征和标签)
3->class MyModel(model) model=Mymodel(搭建网络结构,逐层描述网络)
4->model.compile(选择哪种优化器,损失函数)
5->model.fit(执行训练过程,输入训练集和测试集的特征+标签,batch,迭代次数)
6->验证
导入:这里很容易理解,也就是导入本次实验内容所需要的各种库。在本案例中主要包括以下部分:
蓝框1:
设置电脑gpu工作,如果你的电脑没有gpu就不设置,或者你的gpu显存不够,训练时出问题了,那么就设在为cpu模式
蓝框2:
设置中文显示
对于这里的话我们可以直接复制黏贴,当需要一些其他函数时,只需要添加对应的库文件即可。
设置训练集和测试集:对于神经网络的训练包括了两种数据集合,一个是训练集,一个是测试集。其中训练集数据较多,测试集较少,因为训练一个模型数据越多相对的模型更准确。
本文中利用的数据集在文章下方,该数据集是一个乳腺癌细胞的彩色图像数据集合
本文中数据集处理较为复杂,包括了随机数,显示图片,数据集设置等,我们将分别对代码进行解释。
蓝框1:
本文数据集和之前数字识别和服装识别利用的minist数据集不一样,是存在与本地文件夹中,因此这里数据集的调用方法也不一样。
这里利用了文件夹函数,首先找到数据集的路径,然后通过函数设置路径文件夹,相当于图中的data_dir就是数据集了
蓝框2:
设置数据的尺寸格式
蓝框1 :
这里就是设置训练集了。利用了image_dataset_from_directory(),很明显可以看出来,这是一个图像数据来自文件夹函数。而这个文件夹就是data_dir。
该函数中的变量设置的意思如下:
蓝框2:
这里是吧训练集的标签打印出来,以及设置将要打印出来的图片的尺寸
该部分主要是加速电脑训练的。也可以使用另外的写法,可以参考我的天气识别博客
网络模型搭建:这里也是神经网络的重点了!废话不多说,直接开始!
重点:
现在我们来分析一下图片中经过每层后数据的维度怎么来的
经过卷积层1之后,原数据50x50还是50x50是因为padding=same,保证了输入输出的维度一样,经过池化池pool之后,吃u才能减小一半是因为输出=输入/核大小
其他的卷积层都是按照这个方式来计算的。如果你想看详细的计算过程,可以参考我的天气识别模型,那里模型简单一点,我把整个过程都分析了。
实现天气彩色图像识别_重邮研究森的博客-CSDN博客https://blog.csdn.net/m0_60524373/article/details/126153389
到此,网络模型我们变分析完了。
注意事项:我们发现这里的卷积层每一次的引入了激活函数,这是因为输入是彩色图像,引入激活函数可以更好的提取特征,而正是因为提取特征相对较多,我们又引入了防止过拟合。对于越复杂是数据越要引入激活函数,但是激活函数过多容易过拟合
该部分也同样重要,主要完成模型训练过程中的优化器,损失函数,准确率的设置。
我们结合本文来看。
蓝框1:
对于这三个内容的含义可以参考我的文章开头的另外一篇基础博文进行了详细的介绍
蓝框2:
这里是设置相当于在训练模型时,如果第二轮训练结果比第一轮好,那么保留第二轮参数,如果第三轮训练比第二轮差,则还是保留第三轮参数,最后留下效果最好的那一个。
部分就是执行训练了,那么执行训练肯定需要设置训练集数据及其标签,测试集数据及其标签,训练的epoch
当训练执行完毕,我们就可以拿一个测试集合中或者其他满足格式的数据进行验证了
这里就是绘制训练集和测试集的准确率和损失函数图像
我们取测试集合图片进行验证(这里代码不在上面,是单独测试用的,我放到下面了)
- model = tf.keras.models.load_model('model/26_model.h5')
- plt.figure(figsize=(20, 10))
- for images, labels in val_ds.take(1):
- images = images * 255
- for i in range(batch_size):
- ax = plt.subplot(5, 10, i + 1)
- plt.imshow(images[i].numpy().astype("uint8"))
-
- img_array=tf.expand_dims(images[i],0)
- predictions=model.predict(img_array)
- plt.title(class_names[np.argmax(predictions)])
- plt.axis("off")
- plt.show()
今天引入一个新东西,可以方便我们进行查看测试集合。名字叫做混淆矩阵!
话不多说,先上图。下图就是混淆矩阵画出来的预测值
从上图中我们可以看出,预测和真实值清晰明了的放出来了,但是可惜我们这个本来模型准确率不敢苟同,所以效果差,但这不影响我们简单的使用,代码我放在下面了。
-
- from sklearn.metrics import confusion_matrix
- import seaborn as sns
- import pandas as pd
-
-
- # 定义一个绘制混淆矩阵图的函数
- def plot_cm(labels, predictions):
- # 生成混淆矩阵
- conf_numpy = confusion_matrix(labels, predictions)
- # 将矩阵转化为 DataFrame
- conf_df = pd.DataFrame(conf_numpy, index=class_names, columns=class_names)
-
- plt.figure(figsize=(8, 7))
-
- sns.heatmap(conf_df, annot=True, fmt="d", cmap="BuPu")
-
- plt.title('混淆矩阵', fontsize=15)
- plt.ylabel('真实值', fontsize=14)
- plt.xlabel('预测值', fontsize=14)
- plt.show()
-
- val_pre = []
- val_label = []
-
- for images, labels in val_ds:#这里可以取部分验证数据(.take(1))生成混淆矩阵
- for image, label in zip(images, labels):
- # 需要给图片增加一个维度
- img_array = tf.expand_dims(image, 0)
- # 使用模型预测图片中的人物
- prediction = model.predict(img_array)
-
- val_pre.append(class_names[np.argmax(prediction)])
- val_label.append(class_names[label])
-
- plot_cm(val_label, val_pre)
- plt.show()
最后,再通过一部分代码进行数据验证,代码如下:
- from sklearn import metrics
-
- def test_accuracy_report(model):
- print(metrics.classification_report(val_label, val_pre, target_names=class_names))
- score = model.evaluate(val_ds, verbose=0)
- print('Loss function: %s, accuracy:' % score[0], score[1])
-
- test_accuracy_report(model)