看了Andrew Ng的deeplearning课程,这是其中的一个作业:实现restnet
coursea速度好慢,只能在大佬的博客里找quiz和作业
参考吴恩达《深度学习》课后作业
一、resNet简介
二、
ResNet主要使用了两种块,这取决输入输出的尺寸是否相同
- 标识块(identity_block)
- 卷积块(convolutional_block)
两者的区别,就是identity_block在shortcut上添加了一个卷积层,因为此时输入输出尺寸不相同
; 三、resNet-50的构建
identity_block实现
def identity_block(X, f, filters, stage, block):
"""
:param X: input tensor
:param f: shape for conv2 filter
:param filters: List, the number of filters in the CONV layers of the main path
:param stage: integer,used to name the layers, depending on their position in the network
:param block: name
:return:
"""
conv_name_base = 'res' + str(stage) + block + '_branch'
bn_name_base = 'bn' + str(stage) + block + '_branch'
F1, F2, F3 = filters
X_shortcut = X
X = Conv2D(filters=F1, kernel_size=(1, 1), strides=(1, 1), padding='valid',
name=conv_name_base + '2a', kernel_initializer=glorot_uniform(seed=0))(X)
X = BatchNormalization(axis=3, name=bn_name_base + '2a')(X)
X = Activation('relu')(X)
X = Conv2D(filters=F2, kernel_size=(f, f), strides=(1, 1), padding='same',
name=conv_name_base + '2b', kernel_initializer=glorot_uniform(seed=0))(X)
X = BatchNormalization(axis=3, name=bn_name_base + '2b')(X)
X = Activation('relu')(X)
X = Conv2D(filters=F3, kernel_size=(1, 1), strides=(1, 1), padding='valid',
name=conv_name_base + '2c', kernel_initializer=glorot_uniform(seed=0))(X)
X = BatchNormalization(axis=3, name=bn_name_base + '2c')(X)
X = layers.add([X, X_shortcut])
X = Activation('relu')(X)
return X
convolutional_block实现
def convolutional_block(X, f, filters, stage, block, s=2):
"""
:param X: input tensor
:param f: shape of the second conv
:param filters: list, the number of filters in the CONV layers of the main path
:param stage: Integer, used to name the layers, depending on their position in the network
:param block: same to the parameter stage
:param s: Integer, stride
:return:
"""
conv_name_base = 'res' + str(stage) + block + '_branch'
bn_name_base = 'bn' + str(stage) + block + '_branch'
F1, F2, F3 = filters
X_shortcut = X
X = Conv2D(filters=F1, kernel_size=(1, 1), strides=(s, s), padding='valid',
name=conv_name_base + '2a', kernel_initializer=glorot_uniform(seed=0))(X)
X = BatchNormalization(axis=3, name=bn_name_base + '2a')(X)
X = Activation('relu')(X)
X = Conv2D(filters=F2, kernel_size=(f, f), strides=(1, 1), padding='same',
name=conv_name_base + '2b', kernel_initializer=glorot_uniform(seed=0))(X)
X = BatchNormalization(axis=3, name=bn_name_base + '2b')(X)
X = Activation('relu')(X)
X = Conv2D(filters=F3, kernel_size=(1, 1), strides=(1, 1), padding='valid',
name=conv_name_base + '2c', kernel_initializer=glorot_uniform(seed=0))(X)
X = BatchNormalization(axis=3, name=bn_name_base + '2c')(X)
X_shortcut = Conv2D(filters=F3, kernel_size=(1, 1), strides=(s, s), padding='valid',
name=conv_name_base + '1', kernel_initializer=glorot_uniform(seed=0))(X_shortcut)
X_shortcut = BatchNormalization(axis=3, name=bn_name_base + '1')(X_shortcut)
X = layers.add([X, X_shortcut])
X = Activation('relu')(X)
return X
resNet实现
def ResNet50(input_shape=(64, 64, 3), classes=6):
X_input = Input(input_shape)
X = ZeroPadding2D((3, 3))(X_input)
"""
阶段1:
2D卷积具有64个形状为(7,7)的滤波器,并使用(2,2)步幅,名称是"conv1"。
BatchNorm应用于输入的通道轴。
MaxPooling使用(3,3)窗口和(2,2)步幅。
"""
X = Conv2D(filters=64, kernel_size=(7, 7), strides=(2, 2), name='conv1', kernel_initializer=glorot_uniform(seed=0))(X)
X = BatchNormalization(axis=3, name='bn_conv1')(X)
X = Activation('relu')(X)
X = MaxPooling2D((3, 3), strides=(2, 2))(X)
"""
阶段2:
卷积块使用三组大小为[64,64,256]的滤波器,"f"为3,"s"为1,块为"a"。
2个标识块使用三组大小为[64,64,256]的滤波器,"f"为3,块为"b"和"c"。
"""
X = convolutional_block(X, f=3, filters=[64, 64, 256], stage=2, block='a', s=1)
X = identity_block(X, f=3, filters=[64, 64, 256], stage=2, block='b')
X = identity_block(X, f=3, filters=[64, 64, 256], stage=2, block='c')
"""
阶段3:
卷积块使用三组大小为[128,128,512]的滤波器,"f"为3,"s"为2,块为"a"。
3个标识块使用三组大小为[128,128,512]的滤波器,"f"为3,块为"b","c"和"d"。
"""
X = convolutional_block(X, f=3, filters=[128, 128, 512], stage=3, block='a', s=2)
X = identity_block(X, f=3, filters=[128, 128, 512], stage=3, block='b')
X = identity_block(X, f=3, filters=[128, 128, 512], stage=3, block='c')
X = identity_block(X, f=3, filters=[128, 128, 512], stage=3, block='d')
"""
阶段4:
卷积块使用三组大小为[256、256、1024]的滤波器,"f"为3,"s"为2,块为"a"。
5个标识块使用三组大小为[256、256、1024]的滤波器,"f"为3,块为"b","c","d","e"和"f"。
"""
X = convolutional_block(X, f=3, filters=[256, 256, 1024], stage=4, block='a', s=2)
X = identity_block(X, f=3, filters=[256, 256, 1024], stage=4, block='b')
X = identity_block(X, f=3, filters=[256, 256, 1024], stage=4, block='c')
X = identity_block(X, f=3, filters=[256, 256, 1024], stage=4, block='d')
X = identity_block(X, f=3, filters=[256, 256, 1024], stage=4, block='e')
X = identity_block(X, f=3, filters=[256, 256, 1024], stage=4, block='f')
"""
阶段5:
卷积块使用三组大小为[512、512、2048]的滤波器,"f"为3,"s"为2,块为"a"。
2个标识块使用三组大小为[256、256、2048]的滤波器,"f"为3,块为"b"和"c"。
"""
X = convolutional_block(X, f=3, filters=[512, 512, 2048], stage=5, block='a', s=2)
X = identity_block(X, f=3, filters=[256, 256, 2048], stage=5, block='b')
X = identity_block(X, f=3, filters=[256, 256, 2048], stage=5, block='c')
X = AveragePooling2D(pool_size=(2, 2))(X)
X = Flatten()(X)
X = Dense(classes, activation='softmax', name='fc' + str(classes), kernel_initializer=glorot_uniform(seed=0))(X)
model = Model(inputs=X_input, outputs=X, name='ResNet50')
return model
工具类 resnets_utils.py(包括数据读取,mini-batch划分以及onehot向量转换)
import os
import numpy as np
import tensorflow as tf
import h5py
import math
def load_dataset():
train_dataset = h5py.File('train_signs.h5', "r")
train_set_x_orig = np.array(train_dataset["train_set_x"][:])
train_set_y_orig = np.array(train_dataset["train_set_y"][:])
test_dataset = h5py.File('test_signs.h5', "r")
test_set_x_orig = np.array(test_dataset["test_set_x"][:])
test_set_y_orig = np.array(test_dataset["test_set_y"][:])
classes = np.array(test_dataset["list_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
def random_mini_batches(X, Y, mini_batch_size=64, seed=0):
"""
Creates a list of random minibatches from (X, Y)
Arguments:
X -- input data, of shape (input size, number of examples) (m, Hi, Wi, Ci)
Y -- true "label" vector (containing 0 if cat, 1 if non-cat), of shape (1, number of examples) (m, n_y)
mini_batch_size - size of the mini-batches, integer
seed -- this is only for the purpose of grading, so that you're "random minibatches are the same as ours.
Returns:
mini_batches -- list of synchronous (mini_batch_X, mini_batch_Y)
"""
m = X.shape[0]
mini_batches = []
np.random.seed(seed)
permutation = list(np.random.permutation(m))
shuffled_X = X[permutation, :, :, :]
shuffled_Y = Y[permutation, :]
num_complete_minibatches = math.floor(
m / mini_batch_size)
for k in range(0, num_complete_minibatches):
mini_batch_X = shuffled_X[k * mini_batch_size: k * mini_batch_size + mini_batch_size, :, :, :]
mini_batch_Y = shuffled_Y[k * mini_batch_size: k * mini_batch_size + mini_batch_size, :]
mini_batch = (mini_batch_X, mini_batch_Y)
mini_batches.append(mini_batch)
if m % mini_batch_size != 0:
mini_batch_X = shuffled_X[num_complete_minibatches * mini_batch_size: m, :, :, :]
mini_batch_Y = shuffled_Y[num_complete_minibatches * mini_batch_size: m, :]
mini_batch = (mini_batch_X, mini_batch_Y)
mini_batches.append(mini_batch)
return mini_batches
def convert_to_one_hot(Y, C):
Y = np.eye(C)[Y.reshape(-1)].T
return Y
def forward_propagation_for_predict(X, parameters):
"""
Implements the forward propagation for the model: LINEAR -> RELU -> LINEAR -> RELU -> LINEAR -> SOFTMAX
Arguments:
X -- input dataset placeholder, of shape (input size, number of examples)
parameters -- python dictionary containing your parameters "W1", "b1", "W2", "b2", "W3", "b3"
the shapes are given in initialize_parameters
Returns:
Z3 -- the output of the last LINEAR unit
"""
W1 = parameters['W1']
b1 = parameters['b1']
W2 = parameters['W2']
b2 = parameters['b2']
W3 = parameters['W3']
b3 = parameters['b3']
Z1 = tf.add(tf.matmul(W1, X), b1)
A1 = tf.nn.relu(Z1)
Z2 = tf.add(tf.matmul(W2, A1), b2)
A2 = tf.nn.relu(Z2)
Z3 = tf.add(tf.matmul(W3, A2), b3)
return Z3
def predict(X, parameters):
W1 = tf.convert_to_tensor(parameters["W1"])
b1 = tf.convert_to_tensor(parameters["b1"])
W2 = tf.convert_to_tensor(parameters["W2"])
b2 = tf.convert_to_tensor(parameters["b2"])
W3 = tf.convert_to_tensor(parameters["W3"])
b3 = tf.convert_to_tensor(parameters["b3"])
params = {"W1": W1,
"b1": b1,
"W2": W2,
"b2": b2,
"W3": W3,
"b3": b3}
x = tf.placeholder("float", [12288, 1])
z3 = forward_propagation_for_predict(x, params)
p = tf.argmax(z3)
sess = tf.Session()
prediction = sess.run(p, feed_dict={x: X})
return prediction
模型训练及保存
if __name__ == '__main__':
model = ResNet50(input_shape=(64, 64, 3), classes=6)
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
X_train_orig, Y_train_orig, X_test_orig, Y_test_orig, classes = load_dataset()
X_train = X_train_orig / 255.
X_test = X_test_orig / 255.
Y_train = convert_to_one_hot(Y_train_orig, 6).T
Y_test = convert_to_one_hot(Y_test_orig, 6).T
print("number of training examples = " + str(X_train.shape[0]))
print("number of test examples = " + str(X_test.shape[0]))
print("X_train shape: " + str(X_train.shape))
print("Y_train shape: " + str(Y_train.shape))
print("X_test shape: " + str(X_test.shape))
print("Y_test shape: " + str(Y_test.shape))
model.fit(X_train, Y_train, epochs=20, batch_size=32)
preds = model.evaluate(X_test, Y_test)
print("Loss = " + str(preds[0]))
print("Test Accuracy = " + str(preds[1]))
print("Saving model to disk \n")
mp = "./signs_model.h5"
model.save(mp)
Original: https://blog.csdn.net/qq_43598179/article/details/117604632
Author: Aurevior
Title: 基于keras实现resNet-50残差网络
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/521301/
转载文章受原作者版权保护。转载请注明原作者出处!