码迷,mamicode.com
首页 > Web开发 > 详细

COnvolutional neural network

时间:2016-06-13 21:55:58      阅读:561      评论:0      收藏:0      [点我收藏+]

标签:

这是第二个作业的最后一部分

 

首先进行了一些函数导入并定义误差函数

1 def rel_error(x, y):
2   """ returns relative error """
3 
4   return np.max(np.abs(x - y) / (np.maximum(1e-8, np.abs(x) + np.abs(y))))

上面计算了相对误差,最大是1,最小是0

 

Load数据进来并打印数据的维度

X_val:  (1000, 3, 32, 32)
X_train:  (49000, 3, 32, 32)
X_test:  (1000, 3, 32, 32)
y_val:  (1000,)
y_train:  (49000,)
y_test:  (1000,)

我们要在这里写入自己的数据

 

卷积计算的前向传递过程

 1 def conv_forward_naive(x, w, b, conv_param):
 2   """
 3   A naive implementation of the forward pass for a convolutional layer.
 4 
 5   The input consists of N data points, each with C channels, height H and width
 6   W. We convolve each input with F different filters, where each filter spans
 7   all C channels and has height HH and width HH.
 8 
 9   Input:
10   - x: Input data of shape (N, C, H, W)
11   - w: Filter weights of shape (F, C, HH, WW)
12   - b: Biases, of shape (F,)
13   - conv_param: A dictionary with the following keys:
14     - ‘stride‘: The number of pixels between adjacent receptive fields in the
15       horizontal and vertical directions.
16     - ‘pad‘: The number of pixels that will be used to zero-pad the input.
17 
18   Returns a tuple of:
19   - out: Output data, of shape (N, F, H‘, W‘) where H‘ and W‘ are given by
20     H‘ = 1 + (H + 2 * pad - HH) / stride
21     W‘ = 1 + (W + 2 * pad - WW) / stride
22   - cache: (x, w, b, conv_param)
23   """
24   out = None
25   
26   #############################################################################
27   # TODO: Implement the convolutional forward pass.                           #
28   # Hint: you can use the function np.pad for padding.                        #
29   #############################################################################
30   N,C,H,W = x.shape %读出x的维度
31   F ,C, HH, WW = w.shape %读出w的维度
%stride变量是隔几个像素取一次卷积
%pad变量用来添加图片周围,这样可以防止每次卷积后图片变小
32 stride = conv_param[stride] %conv_param是一个字典,存放了我们需要的变量, 33 num_pad = conv_param[pad] %提取pad值 34 H_p = 1+(H + 2*num_pad - HH)/stride %这个是卷积后的图片的高度 35 W_p = 1+(W+2*num_pad -WW)/stride %卷积后图片的宽度
   %注意pad函数的用法,第二个参数表示在每个维度的左右两次pad多少数值
36 x_pad = np.pad(x,((0,0),(0,0),(num_pad,num_pad),(num_pad,num_pad)),constant) 37 out = np.zeros((N,F,H_p,W_p))%输出值 38 for i in range(N): 39 for j in range(F): 40 for ii in range(0,H,stride): 41 for jj in range(0,W,stride):
% 注意卷积的计算方法
42 out[i,j,ii/stride,jj/stride] = np.sum(x_pad[i,:,ii:ii+HH,jj:jj+WW] * w[j,:,:,:]) + b[j] 43 ############################################################################# 44 # END OF YOUR CODE # 45 ############################################################################# 46 cache = (x, w, b, conv_param) 47 return out, cache

 

 

卷积计算对图片的影响

 

 

卷积计算反向传递过程

 1 def conv_backward_naive(dout, cache):
 2   """
 3   A naive implementation of the backward pass for a convolutional layer.
 4 
 5   Inputs:
 6   - dout: Upstream derivatives.
 7   - cache: A tuple of (x, w, b, conv_param) as in conv_forward_naive
 8 
 9   Returns a tuple of:
10   - dx: Gradient with respect to x
11   - dw: Gradient with respect to w
12   - db: Gradient with respect to b
13   """
14   dx, dw, db = None, None, None
15   #############################################################################
16   # TODO: Implement the convolutional backward pass.                          #
17   #############################################################################
18   x, w, b, conv_param = cache % 取出我们需要的参数
19   num_pad = conv_param[pad]
20   stride = conv_param[stride]
21   N,C,H,W = x.shape % 获得相应的维度值
22   F ,C, HH, WW = w.shape
23   H_p = 1+(H + 2*num_pad - HH)/stride
24   W_p = 1+(W+2*num_pad -WW)/stride
25   
26   %考虑b这个变量对哪些值存在影响,依次加起来,其实是乘以了ones矩阵,再加起来
27   db =np.sum(np.sum( np.sum(dout, axis = 0),axis =1), axis =1 )
28 
29   x_pad = np.pad(x,((0,0),(0,0),(num_pad,num_pad),(num_pad,num_pad)),constant)
30 
31   dw = np.zeros_like(w)
32   for i in range(N):
33     for j in range(F):
34       for ii in range(0,H,stride):
35         for jj in range(0,W,stride):
%注意dw的求解方法
36 dw[j,:,:,:] = dw[j,:,:,:] + x_pad[i,:,ii:ii + HH,jj:jj+WW]*dout[i,j,ii/stride,jj/stride] 37 dx = np.zeros_like(x) 38 #dout_pad = np.pad(x*dout,((0,0),(0,0),(num_pad,num_pad),(num_pad,num_pad)),‘constant‘) 39 dx_temp = np.zeros_like(x_pad) 40 for i in range(N): 41 for j in range(F): 42 for ii in range(0,H,stride): 43 for jj in range(0,W,stride):
%注意dx的求法
44 dx_temp[i,:,ii:ii+HH, jj:jj+WW] = dx_temp[i,:,ii:ii+HH, jj:jj+WW]+w[j,:,:,:]*dout[i,j,ii/stride,jj/stride] 45 46 dx = dx_temp[:,:,num_pad:H+num_pad,num_pad:W+num_pad] 47 48 print "IN function dx.shape:", dx.shape 49 ############################################################################# 50 # END OF YOUR CODE # 51 ############################################################################# 52 return dx, dw, db

 

Max pooling 前向传递过程

 1 def max_pool_forward_naive(x, pool_param):
 2   """
 3   A naive implementation of the forward pass for a max pooling layer.
 4 
 5   Inputs:
 6   - x: Input data, of shape (N, C, H, W)
 7   - pool_param: dictionary with the following keys:
 8     - ‘pool_height‘: The height of each pooling region
 9     - ‘pool_width‘: The width of each pooling region
10     - ‘stride‘: The distance between adjacent pooling regions
11 
12   Returns a tuple of:
13   - out: Output data
14   - cache: (x, pool_param)
15   """
16   out = None
17   
18   #############################################################################
19   # TODO: Implement the max pooling forward pass                              #
20   #############################################################################
21   N,C,H,W = x.shape %x的维度
22   pool_height = pool_param[pool_height] %pool操作所需的参数:高度
23   pool_width = pool_param[pool_width] % pool操作所需的参数:宽度
24   #print "pool_height:", pool_height
25   #print "pool_width:", pool_width
26   #print "x.shape:",x.shape
27   out = np.zeros((N,C,H/pool_height,W/pool_width)) % 输出
28   #print "out.shape:",out.shape
29   for i in range(N):
30     for j in range(C):
31       for ii in range(0,H,pool_height):
32         for jj in range(0,W,pool_width):
33           #print "i:%d, j:%d, ii:%d, jj:%d"%( i,j,ii,jj)

% 注意这个是maxpooling的求法 34 out[i,j,ii/pool_height,jj/pool_width] = np.max(x[i,j,ii:ii+pool_height,jj:jj+pool_width]) 35 36 ############################################################################# 37 # END OF YOUR CODE # 38 ############################################################################# 39 cache = (x, pool_param) 40 return out, cache

 

 

 

Max pooling 后向传递过程

 1 def max_pool_backward_naive(dout, cache):
 2   """
 3   A naive implementation of the backward pass for a max pooling layer.
 4 
 5   Inputs:
 6   - dout: Upstream derivatives
 7   - cache: A tuple of (x, pool_param) as in the forward pass.
 8 
 9   Returns:
10   - dx: Gradient with respect to x
11   """
12   dx = None
13   #############################################################################
14   # TODO: Implement the max pooling backward pass                             #
15   #############################################################################
16   x,pool_param = cache
17   N,C,H,W = x.shape
18   pool_height = pool_param[pool_height]
19   pool_width = pool_param[pool_width]
20   dx = np.zeros_like(x)
21   for i in range(N):
22     for j in range(C):
23       for ii in range(0,H,pool_height):
24         for jj in range(0,W,pool_width):
% 注意maxpooling操作的反向传播求法
25 posi = np.where(x[i,j,ii:ii+pool_height,jj:jj+pool_width]== np.max(x[i,j,ii:ii+pool_height,jj:jj+pool_width])) 26 dx[i,j,ii:ii+pool_height,jj:jj+pool_width][posi] = 1*dout[i,j,ii/pool_height,jj/pool_width] 27 ############################################################################# 28 # END OF YOUR CODE # 29 ############################################################################# 30 return dx

 

 

卷积的快速实现方法(区别于前面的简单的实现方法)(Max pool快速实现类似)

 1 t0 = time()
 2 out_naive, cache_naive = conv_forward_naive(x, w, b, conv_param)
 3 t1 = time()
 4 out_fast, cache_fast = conv_forward_strides(x, w, b, conv_param)
 5 t2 = time()
 6 % 上面是前向的实现


7 t0 = time() 8 dx_naive, dw_naive, db_naive = conv_backward_naive(dout, cache_naive) 9 t1 = time() 10 dx_fast, dw_fast, db_fast = conv_backward_strides(dout, cache_fast) 11 t2 = time()
%后面是后向传播的实现

通过记录t0, t1, t2 可以求出每一段语句运行所需的时间!,注意这种用法

 

将多个子层合在一起,进行梯度求解的数值检查

 1 from cs231n.layer_utils import conv_relu_pool_forward, conv_relu_pool_backward
 2 
 3 x = np.random.randn(2, 3, 16, 16)
 4 w = np.random.randn(3, 3, 3, 3)
 5 b = np.random.randn(3,)
 6 dout = np.random.randn(2, 3, 8, 8)
 7 conv_param = {stride: 1, pad: 1}
 8 pool_param = {pool_height: 2, pool_width: 2, stride: 2}
 9 
10 out, cache = conv_relu_pool_forward(x, w, b, conv_param, pool_param)
11 dx, dw, db = conv_relu_pool_backward(dout, cache)
12 
%注意这里lambda函数的使用方法。 13 dx_num = eval_numerical_gradient_array(lambda x: conv_relu_pool_forward(x, w, b, conv_param, pool_param)[0], x, dout) 14 dw_num = eval_numerical_gradient_array(lambda w: conv_relu_pool_forward(x, w, b, conv_param, pool_param)[0], w, dout) 15 db_num = eval_numerical_gradient_array(lambda b: conv_relu_pool_forward(x, w, b, conv_param, pool_param)[0], b, dout) 16 17 print Testing conv_relu_pool 18 print dx error: , rel_error(dx_num, dx) 19 print dw error: , rel_error(dw_num, dw) 20 print db error: , rel_error(db_num, db)

 

 

做一个三层的卷积神经网络

检查初始解对不对

 1 model = ThreeLayerConvNet()
 2 
 3 N = 50
 4 X = np.random.randn(N, 3, 32, 32)
 5 y = np.random.randint(10, size=N)
 6 
 7 loss, grads = model.loss(X, y)
 8 print Initial loss (no regularization): , loss
 9 
10 model.reg = 0.5
11 loss, grads = model.loss(X, y)
12 print Initial loss (with regularization): , loss

初始的loss值应该在2.3左右

 

 

梯度计算检查

 1 num_inputs = 2
 2 input_dim = (3, 16, 16)
 3 reg = 0.0
 4 num_classes = 10
 5 X = np.random.randn(num_inputs, *input_dim)
 6 y = np.random.randint(num_classes, size=num_inputs)
 7 
 8 model = ThreeLayerConvNet(num_filters=3, filter_size=3,
 9                           input_dim=input_dim, hidden_dim=7,
10                           dtype=np.float64)
11 loss, grads = model.loss(X, y)
12 for param_name in sorted(grads):
13     f = lambda _: model.loss(X, y)[0]
14     param_grad_num = eval_numerical_gradient(f, model.params[param_name], verbose=False, h=1e-6)
15     e = rel_error(param_grad_num, grads[param_name])
16     print %s max relative error: %e % (param_name, rel_error(param_grad_num, grads[param_name]))

 

 

 

对小数据集进行过拟合

 1 num_train = 100
 2 small_data = {
 3   X_train: data[X_train][:num_train],
 4   y_train: data[y_train][:num_train],
 5   X_val: data[X_val],
 6   y_val: data[y_val],
 7 }
 8 
 9 model = ThreeLayerConvNet(weight_scale=1e-2)
10 
11 solver = Solver(model, small_data,
12                 num_epochs=20, batch_size=50,
13                 update_rule=adam,
14                 optim_config={
15                   learning_rate: 2e-4,
16                 },
17                 verbose=True, print_every=1)
18 solver.train()

 

 

 

COnvolutional neural network

标签:

原文地址:http://www.cnblogs.com/lijiajun/p/5582117.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!