欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

神经网络基本原理及其在Python中的实现

程序员文章站 2024-02-05 11:39:46
...

1、神经网络:利用多个神经元去参数化映射函数f的模型。

1.1 感知机不能解决线性不可分问题。

神经网络基本原理及其在Python中的实现

1.2 全连接层

神经网络基本原理及其在Python中的实现

张量方式实现程序如下:

import os
os.environ['TF_CPP_MIN_LOG__LEVEL'] = '2'
import tensorflow as tf
# 创建 W,b 张量
x = tf.random.normal([2,784])
w1 = tf.Variable(tf.random.truncated_normal([784, 256], stddev=0.1))
b1 = tf.Variable(tf.zeros([256]))
o1 = tf.matmul(x,w1) + b1 # 线性变换
o1 = tf.nn.relu(o1) # **函数
print(o1)

层方式实现程序如下:

layers.Dense(units, activation)只需要指定输出节点数 Units 和**函数类型即可。

import os
os.environ['TF_CPP_MIN_LOG__LEVEL'] = '2'
import tensorflow as tf
x = tf.random.normal([4,28*28])
from tensorflow.keras import layers # 导入层模块
# 创建全连接层,指定输出节点数和**函数
fc = layers.Dense(512, activation=tf.nn.relu)
h1 = fc(x) # 通过 fc 类完成一次全连接层的计算
w = fc.kernel # 获取 Dense 类的权值矩阵
b = fc.bias # 获取 Dense 类的偏置向量
# 返回待优化参数列表
all_para = fc.trainable_variables
print(h1,w,b,all_para)

1.3 神经网络

由神经元构成的网络叫做神经网络。

神经网络基本原理及其在Python中的实现

 张量程序实现如下:

import os
os.environ['TF_CPP_MIN_LOG__LEVEL'] = '2'
import tensorflow as tf
x = tf.random.normal([4,28*28])
from tensorflow.keras import layers # 导入层模块
# 隐藏层 1 张量
w1 = tf.Variable(tf.random.truncated_normal([784, 256], stddev=0.1))
b1 = tf.Variable(tf.zeros([256]))
# 隐藏层 2 张量
w2 = tf.Variable(tf.random.truncated_normal([256, 128], stddev=0.1))
b2 = tf.Variable(tf.zeros([128]))
# 隐藏层 3 张量
w3 = tf.Variable(tf.random.truncated_normal([128, 64], stddev=0.1))
b3 = tf.Variable(tf.zeros([64]))
# 输出层张量
w4 = tf.Variable(tf.random.truncated_normal([64, 10], stddev=0.1))
b4 = tf.Variable(tf.zeros([10]))
with tf.GradientTape() as tape: # 梯度记录器
	# x: [b, 28*28]
	# 隐藏层 1 前向计算,[b, 28*28] => [b, 256]
	h1 = aaa@qq.com + tf.broadcast_to(b1, [x.shape[0], 256])
	h1 = tf.nn.relu(h1)
	# 隐藏层 2 前向计算,[b, 256] => [b, 128]
	h2 = aaa@qq.com + b2
	h2 = tf.nn.relu(h2)
	# 隐藏层 3 前向计算,[b, 128] => [b, 64]
	h3 = aaa@qq.com + b3
	h3 = tf.nn.relu(h3)
	# 输出层前向计算,[b, 64] => [b, 10]
	h4 = aaa@qq.com + b4
print(b4,h4)

层方式实现程序如下:

方式一:

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers,Sequential,losses,optimizers,datasets
x = tf.random.normal([4,28*28])
fc1 = layers.Dense(256, activation=tf.nn.relu) # 隐藏层 1
fc2 = layers.Dense(128, activation=tf.nn.relu) # 隐藏层 2
fc3 = layers.Dense(64, activation=tf.nn.relu) # 隐藏层 3
fc4 = layers.Dense(10, activation=None) # 输出层
h1 = fc1(x) # 通过隐藏层 1 得到输出
h2 = fc2(h1) # 通过隐藏层 2 得到输出
h3 = fc3(h2) # 通过隐藏层 3 得到输出
h4 = fc4(h3) # 通过输出层得到网络输出
print(h4)

方式二:

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers,Sequential,losses,optimizers,datasets
x = tf.random.normal([4,28*28])
# 通过 Sequential 容器封装为一个网络类
model = keras.Sequential([
	layers.Dense(256, activation=tf.nn.relu) , # 创建隐藏层 1
	layers.Dense(128, activation=tf.nn.relu) , # 创建隐藏层 2
	layers.Dense(64, activation=tf.nn.relu) , # 创建隐藏层 3
	layers.Dense(10, activation=None) , # 创建输出层
])
out = model(x)
print(out)

结果如下:

神经网络基本原理及其在Python中的实现

神经网络从输入到输出的计算过程叫做前向传播(Forward propagation)。

利用误差反向传播算法进行反向计算的过程也叫反向传播(Backward propagation)。

1.4 **函数

Sigmoid函数:

神经网络基本原理及其在Python中的实现

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers,Sequential,losses,optimizers,datasets
x = tf.linspace(-6.,6.,10)
a = tf.nn.sigmoid(x) # 通过 Sigmoid 函数
print(x,a)

 

 ReLU(修正线性单元)**函数:

神经网络基本原理及其在Python中的实现

函数的实现:

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers,Sequential,losses,optimizers,datasets
x = tf.linspace(-6.,6.,10)
a = tf.nn.relu(x) # 通过 ReLU **函数
print(x,a)

  LeakyReLU函数:

神经网络基本原理及其在Python中的实现

 

神经网络基本原理及其在Python中的实现

程序实现:

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers,Sequential,losses,optimizers,datasets
x = tf.linspace(-6.,6.,10)
a = tf.nn.leaky_relu(x, alpha=0.1) # 通过 LeakyReLU **函数
print(x,a)

Tanh函数:

神经网络基本原理及其在Python中的实现

程序实现:

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers,Sequential,losses,optimizers,datasets
x = tf.linspace(-6.,6.,10)
a = tf.nn.tanh(x) # 通过 tanh **函数
print(x,a)

1.5 输出层设计

Softmax()函数实现区间[0,1],和为1。

神经网络基本原理及其在Python中的实现

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers,Sequential,losses,optimizers,datasets
z = tf.constant([2.,1.,0.1])
a = tf.nn.softmax(z) # 通过 Softmax 函数
print(a)

 将 Softmax 与交叉熵损失函数同时实现:tf.keras.losses.categorical_crossentropy(y_true, y_pred, from_logits=False),其中 y_true 代表了one-hot 编码后的真实标签,y_pred 表示网络的预测值,当 from_logits 设置为 True 时,y_pred 表示须为未经过 Softmax 函数的变量 z;当 from_logits 设置为 False 时,y_pred 表示为经过 Softmax 函数的输出。

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers,Sequential,losses,optimizers,datasets
z = tf.random.normal([2,10]) # 构造输出层的输出
y_onehot = tf.constant([1,3]) # 构造真实值
y_onehot = tf.one_hot(y_onehot, depth=10) # one-hot 编码
# 输出层未使用 Softmax 函数,故 from_logits 设置为 True
loss = keras.losses.categorical_crossentropy(y_onehot,z,from_logits=True)
loss = tf.reduce_mean(loss) # 计算平均交叉熵损失
print(loss)

利用 losses.CategoricalCrossentropy(from_logits)类方式同时实现 Softmax 与交叉熵损失函数的计算。

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers,Sequential,losses,optimizers,datasets
z = tf.random.normal([2,10]) # 构造输出层的输出
y_onehot = tf.constant([1,3]) # 构造真实值
y_onehot = tf.one_hot(y_onehot, depth=10) # one-hot 编码
# 创建 Softmax 与交叉熵计算类,输出层的输出 z 未使用 softmax
criteon = keras.losses.CategoricalCrossentropy(from_logits=True)
loss = criteon(y_onehot,z) # 计算损失
print(loss)

使用 tanh **函数将输出值的范围分布在[−1,1]。

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers,Sequential,losses,optimizers,datasets
x = tf.linspace(-6.,6.,10)
a = tf.tanh(x) # tanh **函数
print(a)

1.6、误差计算

常见的误差计算函数有均方差、交叉熵、KL 散度、Hinge Loss 函数等,其中均方差函数和交叉熵函数在深度学习中比较常见,均方差主要用于回归问题,交叉熵主要用于分类问题。

均方差:

神经网络基本原理及其在Python中的实现

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers,Sequential,losses,optimizers,datasets
o = tf.random.normal([2,10]) # 构造网络输出
y_onehot = tf.constant([1,3]) # 构造真实值
y_onehot = tf.one_hot(y_onehot, depth=10)
loss = keras.losses.MSE(y_onehot, o) # 计算均方差
print(loss)

 方法二:通过层方式实现,对应的类为 keras.losses.MeanSquaredError():

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers,Sequential,losses,optimizers,datasets
o = tf.random.normal([2,10]) # 构造网络输出
y_onehot = tf.constant([1,3]) # 构造真实值
y_onehot = tf.one_hot(y_onehot, depth=10)
loss = keras.losses.MSE(y_onehot, o) # 计算均方差
# 创建 MSE 类
criteon = keras.losses.MeanSquaredError()
loss = criteon(y_onehot,o) # 计算 batch 均方差
print(loss)

交叉熵:

熵在信息学科中也叫信息熵,或者香农熵。熵越大,代表不确定性越大,信息量也就越大。某个分布 (????)的熵定义为

神经网络基本原理及其在Python中的实现

由于P(????) ∈ [0,1], log 2 (????) ≤ 0,因此熵总是大于等于 0。当熵取得最小值 0 时,不确定性为 0。分类问题的 One-hot 编码的分布就是熵为 0 的例子。

利用 tf.math.log()函数来组合计算熵。 

1.7、神经网络类型

卷积神经网络(Convolutional Neural Network,CNN)。

循环神经网络(Recurrent Neural Network,RNN)。

注意力( 机制)网络。

图神经网络。

1.8、油耗预测实例:

#%%
from __future__ import absolute_import, division, print_function, unicode_literals

import pathlib
import os
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
 
import tensorflow as tf

from tensorflow import keras
from tensorflow.keras import layers, losses

print(tf.__version__)
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'


# 在线下载汽车效能数据集
dataset_path = keras.utils.get_file("auto-mpg.data", "http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data")

# 效能(公里数每加仑),气缸数,排量,马力,重量
# 加速度,型号年份,产地
column_names = ['MPG','Cylinders','Displacement','Horsepower','Weight',
                'Acceleration', 'Model Year', 'Origin']
raw_dataset = pd.read_csv(dataset_path, names=column_names,
                      na_values = "?", comment='\t',
                      sep=" ", skipinitialspace=True)

dataset = raw_dataset.copy()
# 查看部分数据
dataset.tail()
dataset.head()
dataset
#%%

#%%

# 统计空白数据,并清除
dataset.isna().sum()
dataset = dataset.dropna()
dataset.isna().sum()
dataset
#%%

# 处理类别型数据,其中origin列代表了类别1,2,3,分布代表产地:美国、欧洲、日本
# 其弹出这一列
origin = dataset.pop('Origin')
# 根据origin列来写入新列
dataset['USA'] = (origin == 1)*1.0
dataset['Europe'] = (origin == 2)*1.0
dataset['Japan'] = (origin == 3)*1.0
dataset.tail()


# 切分为训练集和测试集
train_dataset = dataset.sample(frac=0.8,random_state=0)
test_dataset = dataset.drop(train_dataset.index) 


#%% 统计数据
sns.pairplot(train_dataset[["Cylinders", "Displacement", "Weight", "MPG"]], 
diag_kind="kde")
#%%
# 查看训练集的输入X的统计数据
train_stats = train_dataset.describe()
train_stats.pop("MPG")
train_stats = train_stats.transpose()
train_stats


# 移动MPG油耗效能这一列为真实标签Y
train_labels = train_dataset.pop('MPG')
test_labels = test_dataset.pop('MPG')


# 标准化数据
def norm(x):
  return (x - train_stats['mean']) / train_stats['std']
normed_train_data = norm(train_dataset)
normed_test_data = norm(test_dataset)
#%%

print(normed_train_data.shape,train_labels.shape)
print(normed_test_data.shape, test_labels.shape)
#%%

class Network(keras.Model):
    # 回归网络
    def __init__(self):
        super(Network, self).__init__()
        # 创建3个全连接层
        self.fc1 = layers.Dense(64, activation='relu')
        self.fc2 = layers.Dense(64, activation='relu')
        self.fc3 = layers.Dense(1)

    def call(self, inputs, training=None, mask=None):
        # 依次通过3个全连接层
        x = self.fc1(inputs)
        x = self.fc2(x)
        x = self.fc3(x)

        return x

model = Network()
model.build(input_shape=(None, 9))
model.summary()
optimizer = tf.keras.optimizers.RMSprop(0.001)
train_db = tf.data.Dataset.from_tensor_slices((normed_train_data.values, train_labels.values))
train_db = train_db.shuffle(100).batch(32)

# # 未训练时测试
# example_batch = normed_train_data[:10]
# example_result = model.predict(example_batch)
# example_result

train_mae_losses = []
test_mae_losses = []
for epoch in range(200):
    for step, (x,y) in enumerate(train_db):

        with tf.GradientTape() as tape:
            out = model(x)
            loss = tf.reduce_mean(losses.MSE(y, out))
            mae_loss = tf.reduce_mean(losses.MAE(y, out)) 

        if step % 10 == 0:
            print(epoch, step, float(loss))

        grads = tape.gradient(loss, model.trainable_variables)
        optimizer.apply_gradients(zip(grads, model.trainable_variables))

    train_mae_losses.append(float(mae_loss))
    out = model(tf.constant(normed_test_data.values))
    test_mae_losses.append(tf.reduce_mean(losses.MAE(test_labels, out)))

plt.figure()
plt.xlabel('Epoch')
plt.ylabel('MAE')
plt.plot(train_mae_losses,  label='Train')

plt.plot(test_mae_losses, label='Test')
plt.legend()
 
# plt.ylim([0,10])
plt.legend()
plt.savefig('auto.svg')
plt.show() 

神经网络基本原理及其在Python中的实现

神经网络基本原理及其在Python中的实现

 

 

相关标签: 机器学习