参考博客
题目:
输入人脸图片,判断这个人开不开心。如:
开心输出
1
1
1,不开心输出
0
0
0
一个二分类问题
数据集:
- test_happy.h5:
训练集,维度为:(600,64,64,3),即600张64*64的彩色图片 - train_happy.h5:
测试集,维度为:(150,64,64,3),即150张64*64的彩色图片
环境:
t
f
tf
tf.__
v
e
r
s
i
o
n
version
version__ = ‘
2.5.0
2.5.0
2.5.0’
目的:
搭建卷积层:
C
O
N
V
2
D
⟶
B
a
t
c
h
N
o
r
m
R
E
L
U
⟶
M
A
X
P
O
O
L
⟶
F
L
A
T
T
E
N
⟶
F
U
L
L
Y
C
O
N
N
E
C
T
E
D
⟶
S
I
G
M
O
I
D
CONV2D\overset{Batch Norm}{\longrightarrow}RELU\longrightarrow MAXPOOL\longrightarrow FLATTEN\longrightarrow FULLYCONNECTED\longrightarrow SIGMOID
CONV2D⟶BatchNormRELU⟶MAXPOOL⟶FLATTEN⟶FULLYCONNECTED⟶SIGMOID
加载和处理数据
#加载和处理数据
def load_dataset():
train_dataset = h5py.File('train_happy.h5', "r")
train_set_x_orig = np.array(train_dataset["train_set_x"][:]) # your train set features
train_set_y_orig = np.array(train_dataset["train_set_y"][:]) # your train set labels
test_dataset = h5py.File('test_happy.h5', "r")
test_set_x_orig = np.array(test_dataset["test_set_x"][:]) # your test set features
test_set_y_orig = np.array(test_dataset["test_set_y"][:]) # your test set labels
classes = np.array(test_dataset["list_classes"][:]) # the list of classes
train_set_y_orig = train_set_y_orig.reshape((1, train_set_y_orig.shape[0]))
test_set_y_orig = test_set_y_orig.reshape((1, test_set_y_orig.shape[0]))
return train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes
train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes = load_dataset()
# Normalize image vectors
X_train = train_set_x_orig/255.
X_test = test_set_x_orig/255.
# Reshape
Y_train = train_set_y_orig.T
Y_test = test_set_y_orig.T
print('训练集样本维度:',train_set_x_orig.shape)
print('测试集样本维度:',test_set_x_orig.shape)
创建模型
from keras import Input,Model
from keras.layers import ZeroPadding2D,BatchNormalization,Conv2D,Activation,MaxPool2D,Flatten,Dense
def HappyModel(input_shape):
#Input会自动创建一个palceholer,维度为input_shape
X_input = Input(input_shape)
#使用0进行padding
X = ZeroPadding2D((3,3))(X_input)
#卷积
X = Conv2D(filters = 32,kernel_size = (7,7),strides=(1,1))(X)
#Btach Norm
X = BatchNormalization(axis=3,name='bn0')(X)
#激活函数层
X = Activation("relu")(X)
#最大池化层
X = MaxPool2D(pool_size=(2, 2),name="max_pool")(X)
X = Flatten()(X)
X = Dense(1, activation='sigmoid', name='fc')(X)
model = Model(inputs=X_input, outputs=X, name='HappyModel')
return model
函数讲解
一、输入层
tf.keras.Input(
shape=None, batch_size=None, name=None, dtype=None, sparse=False, tensor=None,
ragged=False, **kwargs
)
- s h a p e : i n t e g e r shape:integer shape:integer元组,(维度,样本数)
- b a t c h s i z e : i n t e g e r batch_size:integer batchsize:integer 一次输入的样本数量
- n a m e : s t r i n g name:string name:string 在模型中要唯一不重复
二、 p a d d i n g padding padding函数,给图片最外层加 0 0 0
tf.keras.layers.ZeroPadding2D(
padding=(1, 1), data_format=None, **kwargs
)
-
p
a
d
d
i
n
g
padding
padding:
i n t → int \to int→高度和宽度都以一个值进行填充
(int,int) → \to →高度以第一个值进行填充,宽度以第二个值进行填充
( ( i n t , i n t ) , ( i n t , i n t ) ) → ( ( t o p _ p a d , b o t t o m _ p a d ) , ( l e f t _ p a d , r i g h t _ p a d ) ) ((int,int),(int,int)) \to((top\_pad, bottom\_pad), (left\_pad, right\_pad)) ((int,int),(int,int))→((top_pad,bottom_pad),(left_pad,right_pad))
三、卷积层
tf.keras.layers.Conv2D(
filters, kernel_size, strides=(1, 1), padding='valid', data_format=None,
dilation_rate=(1, 1), activation=None, use_bias=True,
kernel_initializer='glorot_uniform', bias_initializer='zeros',
kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None,
kernel_constraint=None, bias_constraint=None, **kwargs
)
- f i l t e r s : I n t e g e r filters:Integer filters:Integer 过滤器数量
- k e r n e l _ s i z e : A n i n t e g e r o r t u p l e l i s t o r o f 2 i n t e g e r s , ( h e i g h t , w i d t h ) / [ h e i g h t , w i d t h ] kernel\_size:An\ integer\ or\ tuple\ list\ or \ of\ 2\ integers ,(height,width)/[height,width] kernel_size:An integer or tuple list or of 2 integers,(height,width)/[height,width]
- s t r i d e s : A n i n t e g e r o r t u p l e o r l i s t o f 2 i n t e g e r s strides:\ An\ integer\ or\ tuple\ or\ list\ of\ 2\ integers strides: An integer or tuple or list of 2 integers , 指定卷积沿高度和宽度的步长。
- p a d d i n g : " v a l i d " o r " s a m e " padding:"valid"\ or\ "same" padding:"valid" or "same"
四、Batch Norm
tf.keras.layers.BatchNormalization(
axis=-1, momentum=0.99, epsilon=0.001, center=True, scale=True,
beta_initializer='zeros', gamma_initializer='ones',
moving_mean_initializer='zeros', moving_variance_initializer='ones',
beta_regularizer=None, gamma_regularizer=None, beta_constraint=None,
gamma_constraint=None, renorm=False, renorm_clipping=None, renorm_momentum=0.99,
fused=None, trainable=True, virtual_batch_size=None, adjustment=None, name=None,
**kwargs
)
- a x i s : I n t e g e r , t h e a x i s t h a t s h o u l d b e n o r m a l i z e d axis:\ Integer,\ the\ axis\ that\ should\ be\ normalized axis: Integer, the axis that should be normalized [批量,高度,宽度,通道]
- m o m e n t u m momentum momentum :滑动平均的中的 b e t a u = b e t a ∗ u _ o l d + ( 1 − b e t a ) ∗ u _ n e w beta u=beta*u\_old+(1-beta)*u\_new betau=beta∗u_old+(1−beta)∗u_new
- e p s i l o n : S m a l l f l o a t a d d e d t o v a r i a n c e t o a v o i d d i v i d i n g b y z e r o epsilon :Small\ float\ added\ to\ variance\ to\ avoid\ dividing\ by\ zero epsilon:Small float added to variance to avoid dividing by zero.
- c e n t e r center center:是否忽略 β β β
五、激活函数
tf.keras.layers.Activation(
activation, **kwargs
)
- a c t i v a t i o n : t f . n n . r e l u 或者 " r e l u " activation: tf.nn.relu 或者 "relu" activation:tf.nn.relu或者"relu"
六、最大池化
tf.keras.layers.MaxPool2D(
pool_size=(2, 2), strides=None, padding='valid', data_format=None, **kwargs
)
- p o o l _ s i z e : i n t e g e r o r t u p l e o f 2 i n t e g e r s pool\_size:integer\ or\ tuple\ of\ 2\ integers pool_size:integer or tuple of 2 integers
- s t r i d e s : I n t e g e r , t u p l e o f 2 i n t e g e r s o r N o n e strides:Integer, tuple\ of\ 2\ integers\, or\ None strides:Integer,tuple of 2 integersor None.
- p a d d i n g : " v a l i d " o r " s a m e " padding:"valid" or "same" padding:"valid"or"same"
七、全连接层
tf.keras.layers.Dense(
units, activation=None, use_bias=True, kernel_initializer='glorot_uniform',
bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None,
activity_regularizer=None, kernel_constraint=None, bias_constraint=None,
**kwargs
)
- u n i t s units units:正整数 输出的维度
- a c t i v a t i o n activation activation:激活函数
- u s e _ b i a s use\_bias use_bias:是否使用偏置向量
八、Model的参数
compile(
optimizer='rmsprop', loss=None, metrics=None, loss_weights=None,
weighted_metrics=None, run_eagerly=None, steps_per_execution=None, **kwargs
)
- o p t i m i z e r optimizer optimizer:优化算法 S G D : G r a d i e n t d e s c e n t ( w i t h m o m e n t u m ) o p t i m i z e r 、 R M S p r o p ( r o o t m e a n s q u a r e p r o p ) 、 A d a m SGD:Gradient\ descent\ (with\ momentum)\ optimizer\ \ \ \ 、 RMSprop(root\ mean\ square\ prop\ )\ \ \ \ 、 Adam SGD:Gradient descent (with momentum) optimizer 、RMSprop(root mean square prop ) 、Adam
- l o s s loss loss: B i n a r y C r o s s e n t r o p y BinaryCrossentropy BinaryCrossentropy(正负样本时使用) 、 C a t e g o r i c a l C r o s s e n t r o p y CategoricalCrossentropy CategoricalCrossentropy(预测值与真实值的交叉熵)、 M e a n S q u a r e d E r r o r MeanSquaredError MeanSquaredError(平方根误差)
evaluate(
x=None, y=None, batch_size=None, verbose=1, sample_weight=None, steps=None,
callbacks=None, max_queue_size=10, workers=1, use_multiprocessing=False,
return_dict=False, **kwargs
)
- v e r b o s e : = 0 verbose:=0 verbose:=0时,不输出日志信息 = 1 =1 =1时,带进度条的输出日志信息
- b a t c h _ s i z e batch\_size batch_size:每次进行计算的样本数
模型运行
#创建一个模型实体
happy_model = HappyModel((64,64,3))
#编译模型
happy_model.compile(optimizer="adam",loss="binary_crossentropy", metrics=['accuracy'])
#训练模型
happy_model.fit(X_train, Y_train, epochs=40, batch_size=50)
#评估模型
preds = happy_model.evaluate(X_test, Y_test, batch_size=32)
print ("误差值 = " + str(preds[0]))
print ("准确度 = " + str(preds[1]))
运行结果
Epoch 1/40
12/12 [==============================] - 3s 185ms/step - loss: 1.6428 - accuracy: 0.5875
Epoch 2/40
12/12 [==============================] - 2s 172ms/step - loss: 0.4274 - accuracy: 0.8353
Epoch 3/40
12/12 [==============================] - 3s 212ms/step - loss: 0.2134 - accuracy: 0.9245
Epoch 4/40
12/12 [==============================] - 2s 173ms/step - loss: 0.1238 - accuracy: 0.9588
Epoch 5/40
12/12 [==============================] - 2s 148ms/step - loss: 0.1192 - accuracy: 0.9450
Epoch 6/40
12/12 [==============================] - 2s 139ms/step - loss: 0.0913 - accuracy: 0.9698
Epoch 7/40
12/12 [==============================] - 2s 165ms/step - loss: 0.1027 - accuracy: 0.9756
Epoch 8/40
12/12 [==============================] - 2s 203ms/step - loss: 0.0682 - accuracy: 0.9809
Epoch 9/40
12/12 [==============================] - 2s 157ms/step - loss: 0.0830 - accuracy: 0.9782
Epoch 10/40
12/12 [==============================] - 2s 142ms/step - loss: 0.0526 - accuracy: 0.9885
Epoch 11/40
12/12 [==============================] - 2s 137ms/step - loss: 0.0478 - accuracy: 0.9872
Epoch 12/40
12/12 [==============================] - 2s 145ms/step - loss: 0.0508 - accuracy: 0.9857
Epoch 13/40
12/12 [==============================] - 2s 132ms/step - loss: 0.0331 - accuracy: 0.9929
Epoch 14/40
12/12 [==============================] - 2s 141ms/step - loss: 0.0379 - accuracy: 0.9900
Epoch 15/40
12/12 [==============================] - 2s 138ms/step - loss: 0.0426 - accuracy: 0.9876
Epoch 16/40
12/12 [==============================] - 2s 143ms/step - loss: 0.0322 - accuracy: 0.9898
Epoch 17/40
12/12 [==============================] - 2s 143ms/step - loss: 0.0400 - accuracy: 0.9862
Epoch 18/40
12/12 [==============================] - 2s 161ms/step - loss: 0.0499 - accuracy: 0.9805
Epoch 19/40
12/12 [==============================] - 2s 152ms/step - loss: 0.0458 - accuracy: 0.9879
Epoch 20/40
12/12 [==============================] - 2s 142ms/step - loss: 0.0335 - accuracy: 0.9858
Epoch 21/40
12/12 [==============================] - 2s 147ms/step - loss: 0.0331 - accuracy: 0.9903
Epoch 22/40
12/12 [==============================] - 2s 159ms/step - loss: 0.0339 - accuracy: 0.9873
Epoch 23/40
12/12 [==============================] - 2s 158ms/step - loss: 0.0348 - accuracy: 0.9886
Epoch 24/40
12/12 [==============================] - 2s 145ms/step - loss: 0.0282 - accuracy: 0.9932
Epoch 25/40
12/12 [==============================] - 2s 150ms/step - loss: 0.0236 - accuracy: 0.9946
Epoch 26/40
12/12 [==============================] - 2s 174ms/step - loss: 0.0257 - accuracy: 0.9885
Epoch 27/40
12/12 [==============================] - 3s 261ms/step - loss: 0.0125 - accuracy: 0.9968
Epoch 28/40
12/12 [==============================] - 3s 210ms/step - loss: 0.0162 - accuracy: 0.9937
Epoch 29/40
12/12 [==============================] - 2s 198ms/step - loss: 0.0117 - accuracy: 0.9962
Epoch 30/40
12/12 [==============================] - 2s 175ms/step - loss: 0.0116 - accuracy: 0.9934
Epoch 31/40
12/12 [==============================] - 2s 176ms/step - loss: 0.0128 - accuracy: 0.9949
Epoch 32/40
12/12 [==============================] - 2s 189ms/step - loss: 0.0095 - accuracy: 0.9976
Epoch 33/40
12/12 [==============================] - 2s 161ms/step - loss: 0.0094 - accuracy: 0.9989
Epoch 34/40
12/12 [==============================] - 2s 192ms/step - loss: 0.0099 - accuracy: 0.9964
Epoch 35/40
12/12 [==============================] - 2s 177ms/step - loss: 0.0072 - accuracy: 1.0000
Epoch 36/40
12/12 [==============================] - 2s 197ms/step - loss: 0.0088 - accuracy: 0.9962
Epoch 37/40
12/12 [==============================] - 3s 229ms/step - loss: 0.0103 - accuracy: 0.9946
Epoch 38/40
12/12 [==============================] - 2s 191ms/step - loss: 0.0186 - accuracy: 0.9949
Epoch 39/40
12/12 [==============================] - 2s 186ms/step - loss: 0.0184 - accuracy: 0.9961
Epoch 40/40
12/12 [==============================] - 2s 195ms/step - loss: 0.0148 - accuracy: 0.9980
5/5 [==============================] - 0s 24ms/step - loss: 0.1235 - accuracy: 0.9533
误差值 = 0.12346960604190826
准确度 = 0.95333331823349
新图预测
from skimage import transform
boy = plt.imread('boy.jpeg')
boy = transform.resize(boy,(64,64))
plt.imshow(boy)
plt.show()
x = np.expand_dims(boy, axis=0)
print(happy_model.predict(x/255))
预测结果:
问题总结
- 多看官方tensorflow网站解决问题网址
- 测试数据与现实数据存在数据分布不匹配问题,模型并不能很好的预测网上的图片