DAY22 类神经网路之架设与训练

前面我们介绍了影像辨识的资料前处理方法,今天就要开始教大家架设一个神经网路,并将资料丢入来看看实际的效果,还不了解神经网路的运作概念可以先参考DAY19喔~


一、神经网路组成

一般的神经网路架构可以分为输入层、隐藏层、输出层,输入层将图片像素阵列读取进来,经过隐藏层来做卷积运算、池化...等特徵提取以及权重计算,最後由输出层汇整预测结果并输出,几乎所有的神经网路都是基於这个架构来组成的,见下图:
https://ithelp.ithome.com.tw/upload/images/20210914/20140427o2P2Uut4Jx.jpg
当然,输入层及输出层比较简单、变化相对来说也比较小,因此模型存在最多的差异就是在隐藏层,发展至今,市面上已经有无数个深度学习模型被提出来,全世界的学者、研究专家都在往更高准确率、更快的速度、更小的模型迈进,而具体来说没有哪个模型是绝对最强的,在使用前要考虑很多面向,例如资料适合哪种架构的模型,或是用途等问题。

支援训练类神经网路的API有Tensorflow、Pytorch...等,使用者会依照自己Coding的习惯或是一些API提供的好用功能来选择,今天我们使用的是Tensorflow的API:Keras来做示范,近几年大家也越来越爱使用Pytorch,Google上也开始比较找的到资源去学习,这边也推荐大家尝试不同的工具喔!


二、使用动手架一个神经网路

首先载入一些基本套件

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Activation, Dense

from tensorflow.keras.optimizers import Adam
from tensorflow.keras.metrics import categorical_crossentropy

架设一个神经网路模型

model = Sequential([
    Dense(units=16, input_shape=(1,), activation='relu'),
    Dense(units=32, activation='relu'),
    Dense(units=2, activation='softmax')
])

等等?一个模型这样就架设好了?是的,架设一个神经网路模型就是如此简单,使用这些强大的API就能轻松做到,当然这仅仅是一个最基础的架构,目的是先了解其运作的架构。

稍微解释一下上面的模型架构,我们一开始建立的Sequential大家可以想像成一个容器,模型就是一层一层的堆在这个容器里;而Dense代表的是全连接层(Fully Conected Layer),因为层层的连接在一起而被称为Dense Layer;input_shape则是输入层的维度,根据资料调整;最後是激活函数(Activation),可以把它想像成是对信息的加工,将输入後的数值信息加工後再输出到下一层去计算。

查看模型架构

model.summary()
#param代表总参数量

https://ithelp.ithome.com.tw/upload/images/20210914/20140427FwZPPsm3vc.jpg

编译模型

为了让我们的模型可以进入训练阶段,我们还需要帮它"装备"一下,加强它的战斗力。

model.compile(
optimizer=Adam(learning_rate=0.001), 
loss='sparse_categorical_crossentropy', 
metrics=['accuracy'])

参数说明:

optimizer:一种优化器,主要帮助是模型梯度下降时能找到最优解。

learning_rate:学习率,模型收敛的速度

loss:损失函数,模型的损失值越小越好

metrics:评估指标,使用Accuracy来评估


三、训练模型

模型架设完毕後我们就可以拿资料来训练看看,这里我自己随机生成数据来做训练。

这边我们自己创造一个情境,假设进行一项疫苗的临床实验,30岁以下的年轻人打疫苗後有5%的人会出现不适状况(Label_1)、95%的人不会(Label_0);而30岁以上的人有95%的人打完後会出现不适状况(Label_1)、5%的人会(Label_0)。

创建资料集

import numpy as np
from random import randint

train_samples = []
train_labels = []

for i in range(50):
    # 5%的年轻人会有不适症状
    random_young = randint(1,30)
    train_samples.append(random_young)
    train_labels.append(1)

    # 5%的年长者不会有不适症状
    random_old = randint(31,100)
    train_samples.append(random_old)
    train_labels.append(0)

for i in range(1000):
    # 95%的年轻人不会有不适症状
    random_young = randint(1,30)
    train_samples.append(random_young)
    train_labels.append(0)

    # 95%的年长者会有不适症状
    random_old = randint(31,100)
    train_samples.append(random_old)
    train_labels.append(1)

打乱资料

from sklearn.utils import shuffle
train_samples = np.array(train_samples)
train_labels = np.array(train_labels)
train_samples, train_labels  = shuffle(train_samples, train_labels)

这样一来我们就创造出2100笔资料,其中包含各个年龄以及其对应的Label。

模型训练

model.fit(train_samples,train_labels,batch_size=10, epochs=5, verbose=2)

https://ithelp.ithome.com.tw/upload/images/20210914/20140427LmrEkS9sqO.jpg
大功告成啦!这样我们就训练好一个预测疫苗反应的模型了,可以看到准确率来到0.92,以一个非常简单的架构所建立的模型来说已经算是不错了,自己动手试试看吧!


四、结论

今天我们介绍了一个基本的神经网路中该有的架构,当然有一些超参数或是函数的应用我们都只是简单带过而已,目的是为了让大家先熟悉神经网路的架构,并实际架设了一个简单的模型和数据来训练,之後的章节会再慢慢带大家深入了解其他概念,再会啦!


<<:  DAY21 资料正规化与资料增强(Data Normalization & Data Augmentation)

>>:  DAY23 神经网路优化技巧

BEM 基础介绍 DAY41

BEM B: Block(区块) E: Element(元素) __ 双下底线 M: Modifir...

Android 逆向工程 - 不确定 App 是否有混淆,所以反组译看看 ( 4步骤 )

免责声明 我花了大量的私人时间替专案研究 App 是否混淆成功,混淆结果是否达到需求。虽然我只会做简...

Day3 JDK、JRE 和 JVM 的区别

JDK、JRE 和 JVM 是 Java 编程语言的核心概念!在编程中不使用这些概念,但是作为 Ja...

Day_02: 让 Vite 来开启你的Vue 微谈模组化与演进(上)

Hi Da Gei Ho~ 我是 Winnie , 今天是文章的第二篇,在开始进入主题 Vite之前...

DAY19聚类演算法(kmeans)

昨天介绍完kmeans演算法程序前半段,今天就要把後半段内容给写完: 首先回顾一下昨天我们得到这个分...