神经网络一开始的是由一个二元分类器组成的,用于执行逻辑计算的ANN,后面出现了感知器,感知器不急具有阈值逻辑单元,同时拥有线性逻辑单元,在感知器中使用的都是跳跃函数,数据基本上是分成二元,或者三元,感知器一般由输入层与输出层组成,感知器一般采用类似于梯度下降的方式进行计算,通过多次迭代,计算分类错误的样本对参数w与b的改变,如果最后所有实例分类正确,则得出正确的分类线。
现在利用sklearn.linear_model.Perception来建立单层的阈值逻辑单元(TLU)
from sklearn.linear_model import Perceptron
import numpy as np
from sklearn.datasets import load_iris
iris = load_iris()
x=iris.data[:,(2,3)]
y=(iris.target ==0)
per_clf =Perceptron()
per_clf.fit(x,y)
y_pred = per_clf.predict([[2,0.5]])
y_pred
当单层感知器具有局限时,可以尝试使用多个感知器进行堆叠来消除某些局限。
多层感知器(MLP)是由一个输入层,一个或多个隐藏层(TLU)和一个输出层组成,要训练多层感知器的话需要使用反向传播算法来训练,反向传播的关键是使用了链式计算,可以将求微分的方式进行改变。先将小批量数据送入模型训练,记住每一个中间数据,,然后只用一个损失函数计算误差,计算每一个连接对错误的贡献,然后应用链式法则进行计算,直至输入层,最后执行梯度下降步骤。
MLP中的阶跃函数称之为逻辑函数,有sigmoid,tanh(双曲正切函数),relu(线性整流单位函数)。MLP分为回归MLP与分类MLP,在回归MLP中如果有一个特征,则有一个神经元,而在分类MLP中,每一个类需要一个输出神经元,而且需要使用softmax函数,让输出层总和=1.
使用顺序API构建图像分类器
import tensorflow as tf
from tensorflow import keras
fashion_mnist =keras.datasets.fashion_mnist
(x_train_full,y_train_full),(x_test,y_test) =fashion_mnist.load_data()
x_val,x_train =x_train_full[:5000]/255.0,x_train_full[5000:]/255.0
y_val,y_train =y_train_full[:5000],y_train_full[5000:]
这里/255是为了降低像素强度,让其处于0~1之间
class_names = ["T-shirt/top", "Trouser", "Pullover", "Dress", "Coat",
"Sandal", "Shirt", "Sneaker", "Bag", "Ankle boot"]
建立模型
model =keras.models.Sequential()##适用于顺序连接单层堆栈
model.add(keras.layers.Flatten(input_shape=[28,28]))##作为神经网络的第一层,input_shape为输入实例的形状
model.add(keras.layers.Dense(300,activation='relu'))##这代表了有300个神经元的隐藏层,,使用的是‘relu’为激活函数,其中还包含了一个偏置项
model.add(keras.layers.Dense(100,activation='relu'))
model.add(keras.layers.Dense(10,activation='softmax'))##添加了10个神经元的输出层,使用‘softmax’函数
同时也可以使用keras中model.Sequential的构建模型
##也可以想这样构建
model = keras.models.Sequential([
keras.layers.Flatten(input_shape=[28, 28]),
keras.layers.Dense(300, activation="relu"),
keras.layers.Dense(100, activation="relu"),
keras.layers.Dense(10, activation="softmax")
])
可以通过summary函数输出模型的构成
param为参数个数,同时可以通过model.layers获取模型层列表。
model.layers
可以通过get_weights与set_weighs获得权重与偏置项参数。
weights,biase =model.layers[1].get_weights()
weights##权重
biase##偏执项
在建立模型后,必须进行模型的编译,需要填入损失函数,优化器与评价方法。
##进行模型编译
model.compile(loss='sparse_categorical_crossentropy',
optimizer='sgd',
metrics=['accuracy'])
##loss为损失函数,optimizer为优化器,metrics为指标
##sparse_categorical_crossentropy是将数据进行独热编码后计算其交叉熵
##sgd为梯度下降,acuracy为正确率
history是对模型进行训练以及评估
history =model.fit(x_train,y_train,epochs=30,
validation_data =(x_val,y_val))
evalute是对模型进行评估,计算泛化误差
model.evaluate(x_test,y_test)##进行评估泛化误差
x_new =x_test[:3]
y_proba =model.predict(x_new)
y_proba.round(2)
#y_pred = model.predict_classes(X_new) # deprecated
import numpy as np
y_pred = np.argmax(model.predict(x_new), axis=-1)
y_pred
np.array(class_names)[y_pred]
使用顺序API建立回归MLP
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import tensorflow as tf
from tensorflow import keras
data =fetch_california_housing()
x_train_full,x_test,y_train_full,y_test =train_test_split(data.data,data.target)
x_train,x_val,y_train,y_val =train_test_split(x_train_full,y_train_full)
scaler =StandardScaler()
x_train=scaler.fit_transform(x_train)
x_test=scaler.fit_transform(x_test)
x_val=scaler.fit_transform(x_val)
model =keras.models.Sequential([
keras.layers.Dense(30,activation='relu',input_shape=x_train.shape[1:]),
keras.layers.Dense(1)
])
model.compile(loss='mean_squared_error',optimizer='sgd')##模型编译
history =model.fit(x_train,y_train,epochs=20,validation_data=(x_val,y_val))##设置了20轮进行计算
mse_test = model.evaluate(x_test,y_test)##进行泛化评估
x_new = x_test[:3]
y_pred =model.predict(x_new)
使用函数式API构建复杂模型
复杂模型可能存在多个输入与输出,且隐藏层可能只去一个神经元。
input_ =keras.layers.Input(shape=x_train.shape[1:])
hidden1 =keras.layers.Dense(30,activation='relu')(input_)
hidden2 = keras.layers.Dense(30,activation='relu')(hidden1)
concat =keras.layers.Concatenate()([input_,hidden2])
output_ =keras.layers.Dense(1)(concat)
model =keras.Model(inputs=[input_],outputs=[output_])
在建立了一个隐藏层之后将其作为函数,将其下面的层的结果传递给它。
input_a = keras.layers.Input(shape=[5],name='wide_input')
input_b =keras.layers.Input(shape=[6],name='deep_input')
hidden1 = keras.layers.Dense(30,activation='relu')(input_b)
hidden2 =keras.layers.Dense(30,activation='relu')(hidden1)
concat =keras.layers.Concatenate()([input_a,hidden2])
output =keras.layers.Dense(1,name='output')(concat)
model =keras.Model(inputs=[input_a,input_b],outputs=[output])
model.compile(loss='mse',optimizer=keras.optimizers.SGD(lr=1e-3))
x_train_a,x_train_b=x_train[:,:5],x_train[:,2:]
x_val_a,x_val_b =x_val[:,:5],x_val[:,2:]
x_test_a,x_test_b =x_test[:,:5],x_test[:,2:]
x_new_a,x_new_b =x_test_a[:3],x_test_b[:3]
history =model.fit((x_train_a,x_train_b),y_train,epochs=20,validation_data=((x_val_a,x_val_b),y_val))
mse_test = model.evaluate((x_test_a,x_test_b),y_test)
y_pred =model.predict((x_new_a,x_new_b))
y_pred
由于存在多个输入,所以在训练与预测时需要输入多个数据,同理,输出层也是
output = keras.layers.Dense(1,name='output')(concat)
aux_output =keras.layers.Dense(1,name='aux_output')(hidden2)
model =keras.Model(inputs=[input_a,input_b],outputs = [output,aux_output])
model.compile(loss=['mse','mse'],loss_weights=[0.9,0.1],optimizer='sgd')
history =model.fit([x_train_a,x_train_b],[y_train,y_train],epochs=20,
validation_data=([x_val_a,x_val_b],[y_val,y_val]))
total_loss,main_loss,aux_loss=model.evaluate([x_test_a,x_test_b],[y_test,y_test])
y_pred_main,y_pred_aux =model.predict([x_new_a,x_new_b])
y_pred_main,y_pred_aux