详解神经网络的过程

之前我们知道用卷积神经网络做图片识别

https://ieeexplore.ieee.org/document/726791/citations#citations

可是卷积神经网络是怎么工作的呢?
本文专门完整走一边神经网络,看看数据都发生了什么变化。

需要用到的库有tensorflow、matplotlib和cv2

import tensorflow as tf
import matplotlib.pyplot as plt
import cv2

读取图片

首先我们读取一张图片,然后改成320×320的尺寸

img = cv2.imread('doll.png')
b,g,r = cv2.split(img)
img = cv2.merge([r,g,b])
img = cv2.resize(img, (320, 320))
img = img / 255.0

可以查看一下图片是一个320×320×3的数组

array([[[0.6627451 , 0.67843137, 0.6745098 ],
        [0.6627451 , 0.67843137, 0.6745098 ],
        [0.6627451 , 0.67843137, 0.6745098 ],
        ...,
        [0.49019608, 0.49019608, 0.48235294],
        [0.49803922, 0.48235294, 0.47843137],
        [0.49803922, 0.48235294, 0.47843137]],

       [[0.6627451 , 0.68627451, 0.67843137],
        [0.6627451 , 0.68627451, 0.67843137],
        [0.6627451 , 0.68627451, 0.67843137],
        ...,
        [0.49019608, 0.49019608, 0.48235294],
        [0.49019608, 0.48627451, 0.47843137],
        [0.49019608, 0.48627451, 0.47843137]],

       [[0.6627451 , 0.69019608, 0.69019608],
        [0.6627451 , 0.68627451, 0.68627451],
        [0.6627451 , 0.68627451, 0.68627451],
        ...,
        [0.49019608, 0.49019608, 0.48235294],
        [0.49019608, 0.48627451, 0.47843137],
        [0.49019608, 0.48627451, 0.47843137]],

       ...,
...

        [0.6627451 , 0.67843137, 0.6745098 ],
        ...,
        [0.32156863, 0.25098039, 0.20392157],
        [0.31764706, 0.24705882, 0.2       ],
        [0.31372549, 0.24313725, 0.19607843]]])

cv2的功能比较多,比如改变尺寸,如果不需要,只用自带的函数就可以完成

在matplatlib里面显示一下为

plt.imshow(img)
plt.show()

详解神经网络的过程

卷积神经网络

现在我们就把这张图片输入一下神经网络模型,看看每一步的变化。

卷积

总共如下重要参数

https://tensorflow.google.cn/api_docs/python/tf/keras/layers/Conv2D

  • filters: 输出空间的维度
  • kernel_size: 卷积核的宽高,可以数组或者元祖,如果宽高一样可以是一个整数
  • strides: 步长,卷积在宽高的步长
  • padding: 边界,string类型的SAME或VALID,不区分大小写,SAME代表了上下左右的边界补0,VALID代表没有边界
  • activation: 激活函数,一般使用ReLU作为激活函数
  • dilation_rate: 膨胀率,卷积中间补0,膨胀率和步长不能同时大于1
tf.keras.backend.set_floatx('float64')
conv1 = tf.keras.layers.Conv2D(16, 2, input_shape=(320,320,3))
img_conv1 = conv1(tf.reshape(img, (1, 320, 320, 3)))

正常应该是输入一组320×320×3的图片
现在虽然只有一张也是要放入一个数组中所以reshape(1, 320, 320, 3)

输入的刚才的img,也就是320×320的三通道的1张图片

因为 filters=16,所以输出了16张图片

卷积核是2×2,所以320×320变成了319×319

TensorShape([1, 319, 319, 16])

注意,之前的3代表的是RGB三通道,现在的16代表了16个不同的卷积后的图片

返回的319×319的16张图片如下

详解神经网络的过程
我们修改一下参数,现在把kernel_size设置为4,步长设置为2,并且增加了relu为激活函数
conv2 = tf.keras.layers.Conv2D(16, 4, 2, activation=tf.nn.relu)
img_conv2 = conv2(img_conv1)
fig, axes = plt.subplots(4, 4, figsize=(6,6))
for m in range(4):
  for n in range(4):
    axes[m, n].imshow(img_conv2[0,:,:,m*4 + n])
plt.show()

TensorShape([1, 158, 158, 16])

图如下

详解神经网络的过程

因为步长为2,所以尺寸从之前的319减少到了158,少了一半

因为设置了relu激活函数,所以很多数据没到阈值直接变成0,所以很多图片直接”黑”了,因为0是黑色

池化

池化是为了防止过拟合,表现效果就是尺寸更小

pool1 = tf.keras.layers.MaxPool2D()
img_pool1 = pool1(img_conv2)
fig, axes = plt.subplots(4, 4, figsize=(6,6))
for m in range(4):
  for n in range(4):
    axes[m, n].imshow(img_pool1[0,:,:,m*4 + n])
plt.show()
img_pool1.shape

TensorShape([1, 79, 79, 16])

池化之后从之前的158降低到了79

如图

详解神经网络的过程

再来一次卷积和池化,并且把深度加到64

conv3 = tf.keras.layers.Conv2D(32, 2, activation='relu')
img_conv3 = conv3(img_pool1)
conv4 = tf.keras.layers.Conv2D(64, 2, activation='relu')
img_conv4 = conv4(img_conv3)
pool2 = tf.keras.layers.MaxPool2D()
img_pool2 = pool2(img_conv4)
fig, axes = plt.subplots(8, 8, figsize=(8,8))
for m in range(8):
  for n in range(8):
    axes[m, n].imshow(img_pool2[0,:,:,m*8 + n])
plt.show()
img_pool2.shape

详解神经网络的过程

压平

现在要把38×38×64的三维向量拉平,变成一维向量,计算机算的数据最好是一维

img_flatten = tf.keras.layers.Flatten()(img_pool2)
img_flatten.shape

TensorShape([1, 92416])

全链接

最后使用dense创建选链接,unit设置为多少就会变成多少个数据

img_dense1 = tf.keras.layers.Dense(32, activation=tf.nn.relu)(img_flatten)
img_dense1.shape

TensorShape([1, 32])

比如最终的图片分类是10个,那么最终就设置10个单位,一般留一个梯度,缓缓下降到最终的单位

cls = tf.keras.layers.Dense(10, activation=tf.nn.softmax)(img_dense1)
cls

可以看到,cls中的10个数据,就代表了每一个分类的概率

<tf.tensor: shape="(1," 10), dtype="float64," numpy="array([[0.0998901" , 0.09763801, 0.09610229, 0.10639109, 0.12393067, 0.08850211, 0.09905299, 0.08858827, 0.10362383, 0.09628064]])>
</tf.tensor:>

详解神经网络的过程
可以看到标签4的几率高一些

因为没有训练,数据比较平均

源代码:https://gitee.com/thales-ucas/deep-learning/blob/main/cnn.ipynb

Original: https://blog.csdn.net/minamto/article/details/124202495
Author: 源霓码
Title: 详解神经网络的过程

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/691577/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球