-
Notifications
You must be signed in to change notification settings - Fork 0
/
cnn_model.py
130 lines (103 loc) · 4.44 KB
/
cnn_model.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import tensorflow as tf
import numpy as np
def conv2d_maxpool(x_tensor, conv_num_outputs, conv_ksize, conv_strides, pool_ksize, pool_strides):
"""
Apply convolution then max pooling to x_tensor
:param x_tensor: TensorFlow Tensor
:param conv_num_outputs: Number of outputs for the convolutional layer
:param conv_ksize: kernal size 2-D Tuple for the convolutional layer
:param conv_strides: Stride 2-D Tuple for convolution
:param pool_ksize: kernal size 2-D Tuple for pool
:param pool_strides: Stride 2-D Tuple for pool
: return: A tensor that represents convolution and max pooling of x_tensor
"""
# Weights
W_shape = list(conv_ksize) + [int(x_tensor.shape[3]), conv_num_outputs]
W = tf.Variable(tf.truncated_normal(W_shape, stddev=.05))
# Apply convolution
x = tf.nn.conv2d(
x_tensor, W,
strides = [1] + list(conv_strides) + [1],
padding = 'SAME'
)
# Add bias
b = tf.Variable(tf.zeros([conv_num_outputs]))
x = tf.nn.bias_add(x, b)
# Nonlinear activation (ReLU)
x = tf.nn.relu(x)
# Max pooling
return tf.nn.max_pool(
x,
ksize = [1] + list(pool_ksize) + [1],
strides = [1] + list(pool_strides) + [1],
padding = 'SAME'
)
def flatten(x_tensor):
"""
Flatten x_tensor to (Batch Size, Flattened Image Size)
: x_tensor: A tensor of size (Batch Size, ...), where ... are the image dimensions.
: return: A tensor of size (Batch Size, Flattened Image Size).
"""
return tf.reshape(x_tensor, [-1, np.prod(x_tensor.shape.as_list()[1:])])
def fully_conn(x_tensor, num_outputs):
"""
Apply a fully connected layer to x_tensor using weight and bias
: x_tensor: A 2-D tensor where the first dimension is batch size.
: num_outputs: The number of output that the new tensor should be.
: return: A 2-D tensor where the second dimension is num_outputs.
"""
# Weights and bias
W = tf.Variable(tf.truncated_normal([int(x_tensor.shape[1]), num_outputs], stddev=.05))
b = tf.Variable(tf.zeros([num_outputs]))
# The fully connected layer
x = tf.add(tf.matmul(x_tensor, W), b)
# ReLU activation function
return tf.nn.relu(x)
def output(x_tensor, num_outputs):
"""
Apply a output layer to x_tensor using weight and bias
: x_tensor: A 2-D tensor where the first dimension is batch size.
: num_outputs: The number of output that the new tensor should be.
: return: A 2-D tensor where the second dimension is num_outputs.
"""
# Weights and bias
W = tf.Variable(tf.truncated_normal([int(x_tensor.shape[1]), num_outputs], stddev=.05))
b = tf.Variable(tf.zeros([num_outputs]))
# The output layer
return tf.add(tf.matmul(x_tensor, W), b)
def conv_net(x, keep_prob=None):
"""
Create a convolutional neural network model
: x: Placeholder tensor that holds image data.
: keep_prob: Placeholder tensor that hold dropout keep probability.
: return: Tensor that represents logits
"""
# 3 convolution layers with max pooling
# All layers with same kernel, stride and maxpooling params
x = conv2d_maxpool(x, 64, (3,3), (1,1), (2,2), (2,2))
x = conv2d_maxpool(x, 128, (3,3), (1,1), (2,2), (2,2))
x = conv2d_maxpool(x, 256, (3,3), (1,1), (2,2), (2,2))
# dropout after convolutions
if keep_prob: x = tf.nn.dropout(x, keep_prob)
# flatten layer
x = flatten(x)
# 1 fully connected layer followed by dropout
x = fully_conn(x, 1024)
if keep_prob: x = tf.nn.dropout(x, keep_prob)
# output layer
return output(x, 10)
def conv_net_test(x, keep_prob):
# Inputs
x = tf.placeholder(tf.float32, [None, 32, 32, 3], name="x")
y = tf.placeholder(tf.float32, [None, 10], name="y")
keep_prob = tf.placeholder(tf.float32, name="keep_prob")
# Model
logits = conv_net(x, keep_prob)
# Name logits Tensor, so that is can be loaded from disk after training
logits = tf.identity(logits, name='logits')
# Loss and Optimizer
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y))
optimizer = tf.train.AdamOptimizer().minimize(cost)
# Accuracy
correct_pred = tf.equal(tf.argmax(logits, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32), name='accuracy')