# coding: utf-8
import os
import codecs
import numpy as np
from sklearn.preprocessing import scale
import tensorflow as tf
def weight_variable(shape):
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)
def bias_variable(shape):
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial)
def conv2d(x, W):
# stride [1, x_movement, y_movement, 1]
# must have strides[0] = stride[4] = 1
return tf.nn.conv2d(x, W, strides=[1, 2, 2, 1], padding='SAME')
def max_pool_2x2(x):
# must have strides[0] = stride[4] = 1
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1], padding='SAME')
if __name__ == '__main__':
# define placeholder for inputs to network
xs = tf.placeholder(tf.float32, [None, 52*52]) # number of dimension
ys = tf.placeholder(tf.float32, [None, 6]) # number of class
keep_prob = tf.placeholder(tf.float32)
x_image = tf.reshape(xs, [-1, 52, 52, 1]) #
# print(x_image.shape) # [n_samples, 10, 10, 1]
# conv1 layer
W_conv1 = weight_variable([5, 5, 1, 32]) # patch: 5*5 in size: 1; out size 32
b_conv1 = bias_variable([32])
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
print("h_conv1 %s" % h_conv1.shape)
# valid: h_conv1 (?, 24, 24, 32)
h_pool1 = max_pool_2x2(h_conv1)
print("h_pool1 %s" % h_pool1.shape)
# valid: h_pool1 (?, 12, 12, 32)
# (10-2+1*2)/2+1=
# conv2 layer
W_conv2 = weight_variable([5, 5, 32, 64]) # patch: 5*5 in size: 32 out size 64
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
print("h_conv2: %s" % h_conv2.shape)
# valid: h_conv2: (?, 8, 8, 64)
h_pool2 = max_pool_2x2(h_conv2)
print("pool2_shape: %s" % h_pool2.shape)
# valid: pool2_shape: (?, 4, 4, 64)
# func1 layer
W_fc1 = weight_variable([4 * 4 * 64, 1024])
b_fc1 = bias_variable([1024])
# [n_samples, 7, 7, 64] ->[n_samples, 7*7*64]
h_pool2_flat = tf.reshape(h_pool2, [-1, 4 * 4 * 64])
# all samples * 7*7*64 , 7*7*64, 1024, --> all samples 1024, 每个样本1024维
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
print("h_fc1: %s" % h_fc1.shape)
# valid: h_fc1: (?, 1024)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob=keep_prob)
print("h_fc1_drop: %s" % h_fc1_drop.shape)
# valid: h_fc1_drop: (?, 1024)
# func2 layer
W_fc2 = weight_variable([1024, 6])
b_fc2 = bias_variable([6])
tar = tf.matmul(h_fc1_drop, W_fc2) + b_fc2
print("tar: %s" % tar.shape)
# valid: tar: (?, 6)
prediction = tf.nn.softmax(tar)
# the error between prediction and real data
cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction),
reduction_indices=[1]))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
sess = tf.Session()
# important step
sess.run(tf.global_variables_initializer())
"""
conv kernel: [5, 5] strides: [1, 1]
pool kernel: [2, 2] strides: [2, 2]
SAME:
28*28
h_conv1 (?, 28, 28, 32) ceil(长或宽/stride)
h_pool1 (?, 14, 14, 32)
h_conv2: (?, 14, 14, 64)
pool2_shape: (?, 7, 7, 64)
h_fc1: (?, 1024)
h_fc1_drop: (?, 1024)
tar: (?, 6)
26*26
h_conv1 (?, 26, 26, 32)
h_pool1 (?, 13, 13, 32)
h_conv2: (?, 13, 13, 64)
pool2_shape: (?, 7, 7, 64)
h_fc1: (?, 1024)
h_fc1_drop: (?, 1024)
tar: (?, 6)
VALID:
28*28
h_conv1 (?, 24, 24, 32) (28-5+1)/1=24
h_pool1 (?, 12, 12, 32) ceil(24-2+1)/2=12
h_conv2: (?, 8, 8, 64) (8-5+1)/1=4
pool2_shape: (?, 4, 4, 64)
h_fc1: (?, 1024)
h_fc1_drop: (?, 1024)
tar: (?, 6)
26*26
h_conv1 (?, 22, 22, 32) (26-5+1)/1=22
h_pool1 (?, 11, 11, 32) ceil(22-2+1)/2=11
h_conv2: (?, 7, 7, 64) (11-5+1)/1=7
pool2_shape: (?, 3, 3, 64)
h_fc1: (?, 1024)
h_fc1_drop: (?, 1024)
tar: (?, 6)
"""
"""
conv kernel: [5, 5] strides: [2, 2]
pool kernel: [2, 2] strides: [2, 2]
VALID:
52*52
h_conv1 (?, 24, 24, 32) (52-5+1)/2=48/2=24
h_pool1 (?, 12, 12, 32) ceil(24-2+1)/2=11.5
h_conv2: (?, 4, 4, 64) (12-5+1)/2=4
pool2_shape: (?, 2, 2, 64) (4-2+1)/2=1.5
h_fc1: (?, 1024)
h_fc1_drop: (?, 1024)
tar: (?, 6)
SAME:
52*52
h_conv1 (?, 26, 26, 32) 52/2=26
h_pool1 (?, 13, 13, 32) 26/2=13
h_conv2: (?, 7, 7, 64) ceil 13/2=6.5=7
pool2_shape: (?, 4, 4, 64) 7/2=3.5=4
h_fc1: (?, 1024)
h_fc1_drop: (?, 1024)
tar: (?, 6)
"""
卷积层和池化层的计算公式相同:
若没有边缘填充,padding=VALID,计算公式如下: O=ceil((W-K+1)/S) 若有边缘填充,padding=SAME,计算公式如下: O=ceil(W/S) O是输出尺寸,W是输入尺寸的长或宽,K是过滤器尺寸,P是边缘填充,S是步长,ceil()表示向上取整函数。