Register
Login
Resources
Docs Blog Datasets Glossary Case Studies Tutorials & Webinars
Product
Data Engine LLMs Platform Enterprise
Pricing Explore
Connect to our Discord channel

dnn.md 7.2 KB

You have to be logged in to leave a comment. Sign In

DNN(Deep-Learning Neural Network)

接下来介绍比较常见的全连接层网络(fully-connected feedfoward nerural network)

名词解释

首先介绍一下神经网络的基本架构,以一个神经元为例

输入是一个向量权重(weights)也是一个矩阵

把两个矩阵进行相乘,最后加上偏差(bias),即w1 * x1 + w2 * x2 + b

神经元里面会有一个激活函数(activation),比如sigmoid,Relu等等,然后将这个结果当作未知量输入神经元所代表的函数

神经网络分为三个层次,从左到右分别为输入层(Input Layer)隐含层(Hidden Layer)输出层(Output Layer) 。当然在输出之前还得经过softmax,这里只是广义的网络架构。输入层和输出层没必要赘言。一个隐含层有很多神经元(neuron),神经元的数目是你可以设置的参数。

何为 全连接(fully-connected) 呢?

每一个输入跟神经元必定两两相连

------------------------------------------------------------------------图片来源----------------------------------------------------------------------------

那么,肯定有人问了

Deep or not?

Universality Theorem

Any Deep Neuron Network can be replaced by one-hidden-layer neuron network.

于是有人说,我都可以用一层代替很多层了,那为什么还用Deep,根本没必要嘛

Why Deep?

确实一个很宽的隐含层可以代替很多层,但是效率必须纳入比较范围

如果浅层和深层比较,按照控制变量法,两个参数数量必须一样,否则结果会有偏差

举个例子,接下来我要通过图片来分辨长发男,短发男,长发女,短发女。

浅层做法:

那我们联系一下现实,现实中长发男不大好找诶,这就意味着这类数据量很少,train出的结果很糟。

我们都知道如果问题比较复杂的时候,可以将问题分为几个小问题,算法中有个思维是分而治之(Divide and Conquer)。这里要介绍一下模组化(Modularization)

继续上面的例子,我们可以先分辨是男是女和是长发还是短发

------------------------------------------------------------------------图片来源----------------------------------------------------------------------------

这样的话,数据量都是够的,train出的结果不会很糟

------------------------------------------------------------------------图片来源----------------------------------------------------------------------------

通过模组化用两层神经网络可以解决数据量不足的问题,这样train出的结果比一层比起来肯定是好的多的

这也可以解释其实当我们数据不够的时候,用Deep Neuron Network其实train出的结果比其他好一点

而且神奇的是,ModularizationDeepLearning的过程中会自动从训练数据中学得,Deep的过程中会把一个复杂的问题分成若干个Simple Function,每一个各司其职,就像是写代码的时候会写一个函数,然后再需要用的时候,call一下函数名就行了

Deep is necessary.

接下来,以手写数字识别(Mnist)为例代码实操一下

import matplotlib.pyplot as plt
import numpy as np
from tensorflow import keras
from tensorflow.keras import layers
import sys
import matplotlib as mpl
import tensorflow as tf

# 不同库版本,使用本代码需要查看
print(sys.version_info)
for module in mpl,np,tf,keras:
  print(module.__name__,module.__version__)

'''
sys.version_info(major=3, minor=6, micro=9, releaselevel='final', serial=0)
matplotlib 3.3.4
numpy 1.16.0
tensorflow 1.14.0
tensorflow.python.keras.api._v1.keras 2.2.4-tf
'''
# If you get numpy futurewarning,then try numpy 1.16.0

# Load train and test
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()

# Reshape to dense standard input
x_train = x_train.reshape(60000, 784)
x_test = x_test.reshape(10000, 784)

# Scale images to the [0, 1] range
x_train = x_train.astype("float32") / 255
x_test = x_test.astype("float32") / 255

# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, 10)
y_test = keras.utils.to_categorical(y_test, 10)

model = keras.Sequential(
    [
        keras.Input(shape=(28 * 28)),
        layers.Dense(128, activation="relu"),
        layers.Dense(128, activation="relu"),
        layers.Dense(128, activation="relu"),
        layers.Dense(10, activation="softmax"),
    ]
)

model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])

model.summary()

history = model.fit(x_train, y_train, batch_size=128, epochs=15, validation_split=0.2)
score = model.evaluate(x_test, y_test)

print("Test Loss:", score[0])
print("Test Accuracy", score[1])

# Test Loss: 0.11334700882434845
# Test Accuracy 0.9750999808311462
# 注意天下几乎没有两个相同的准确率,因为你是random出来的,在epoch之前会randomly initialize parameters

# visualize accuracy and loss
def plot_(history,label):
    plt.plot(history.history[label])
    plt.plot(history.history["val_" + label])
    plt.title("model " + label)
    plt.ylabel(label)
    plt.xlabel("epoch")
    plt.legend(["train","test"],loc = "upper left")
    plt.show()

plot_(history,"acc")
plot_(history,"loss")

'''
@Tool : Tensorflow 2.x
Transform acc,val_acc above into accuracy,val_accuracy
'''
 

这里跟CNN 其实shape的处理是不一样的。在CNN中你必须再加一个维度来表示channel,而DNN这里是不需要的。读者也可以把print一下train_data.shape,会发现是(60000,28,28)。60000是数据的数目。输入shape应该是 28 * 28 = 784,为了与输入shape匹配,需要一开始reshape成(60000,784)

注意:千万别把 28 * 28 写出 (28,28)!否则会报错

ValueError: Input 0 of layer sequential is incompatible with the layer: expected axis -1 of input shape to have value 28 but received input with shape (128, 784)
Tip!

Press p or to see the previous file or, n or to see the next file

Comments

Loading...