[Deep Learning] 6-4 Rede Neural Convolucional - Implementação de CNN

Implementação da CNN
insira a descrição da imagem aqui
A composição da rede é "Convolution - ReLU - Pooling -Affine - ReLU - Affine - Softmax", e a implementamos como uma classe chamada SimpleConvNet .
Primeiro olhe para a inicialização do SimpleConvNet ( init ), pegue os seguintes parâmetros.
input_dim - Dimensões dos dados de entrada: (canal, altura, comprimento)
conv_param - hiperparâmetros (dicionário) da camada convolucional. As palavras-chave do dicionário são as seguintes:
filter_num—o número de filtros
filter_size—o tamanho do filtro
stride—the stride
pad—preenchimento
hidden_size—o número de neurônios na camada oculta (conexão completa)
output_size——a camada de saída ( conexão completa) O número de neurônios
weitght_int_std - o desvio padrão do peso na inicialização

Aqui, os hiperparâmetros da camada convolucional são passados ​​por um dicionário chamado conv_param.

A implementação do SimpleConvNet é a seguinte:

class SimpleConvNet:
	def __init__(self, input_dim=(1,28,28), conv_param={
    
    'filter_num':30, 'filter_size':5,'pad':0, 'stride':1}, hidden_size=100,output_size=10, weight_init_std=0.01):
		filter_num = conv_param['filter_num']
		filter_size = conv_param['filter_size']
		filter_pad = conv_param['filter_pad']
		filter_stride = conv_param['filter_stride']
		input_size = input_dim[1]
		conv_output_size = (input_size - filter_size + 2*filter_pad) / filter_stride +1
		pool_output_size = int(filter_num * (conv_output_size /2) * (conv_output_size/2))

		# 这里将由初始化参数传入的卷积层的超参数从字典中取了出来(以方便后面使用),然后,计算卷积层的输出大小。

		# 接下来是权重参数的初始化部分
		self.params = {
    
    }
		self.params['W1'] = weight_init_std * np.random.randn(filter_num, input_dim[0],filter_size, filter_size)
		self.params['b1'] = np.zeros(filter_num)

		self.params['W2'] = weight_init_std * np.random.randn(pool_output_size, hidden_size)
		self.params['b2'] = np.zeros(hidden_size)

		self.params['W3'] = weight_init_std * np.random.randn(hidden_size, output_size)
		self.params['b3'] = np.zeros(output_size)

		# 最后生成必要的层
		self.layers = OrderDict()
		self.layers['Conv1'] = Convolution(self.params['W1'],self.params['b1'],conv_param['stride'],conv_param['pad'])
		self.layers['Relu1']= Relu()
		self.layers['Pool1']= Pooling(poo_h=2,pool_w=2,stride=2)
		self.layers['Affine1'] = Affine(self.params['W2'],self.params['b2'])
		self.layers['Relu2'] = Relu()
		self,layers['Affine2']= Affine(self.params['W3'],self.params['b3'])
		self.last_layer = SoftmaxWithLoss()
		# 从最前面开始按顺序向有序字典(OrderedDict)的layers中添加层。只有最后的SoftmaxWithLoss层被添加到别的变量LastLayer中。

O acima é o processamento realizado na inicialização do simpleConvNet. Após uma inicialização como essa, o método de previsão para raciocínio e o método de perda para calcular o valor da função de perda podem ser implementados da seguinte maneira

def predict(self, x):
	for layer in self.layers.values():
		x = layer.forward(x)
	return x

def loss(self, x, t):
	y = self.predict(x)
	return self.lastLayer.forward(y,t)

Aqui, o parâmetro x são os dados de entrada e t é o rótulo supervisionado. O método de previsão para inferência chama as camadas adicionadas sequencialmente desde o início e passa o resultado para a próxima camada.

No método de perda para encontrar a função de perda, além do processamento de encaminhamento usando o método de previsão, o processamento de encaminhamento continuará até que a camada SoftmaxwithLoss final seja atingida .

A seguir está a implementação do código com base no método de retropropagação de erro para encontrar o gradiente

def gradient(self,x,t):
	#forward
	self.loss(x,t)
	#backward
	dout = 1
	dout = self.lastLayer.backward(dout)
	
	layers = list(self.layers.values())
	layers.reverse()
	for layer in layers:
		dout = layer.backward(dout)
	# 设定
	grads={
    
    }
	grads['W1'] = self,layers['Conv1'].dw
	grads['b1'] = self.layers['Conv1'].db
	grads['W2'] = self.layers['Affine1'].dw
	grads['b2'] = self,layers['Affine1'].db
	grads['W3'] = self,layers['Affine2'].dw
	grads['b3'] = self.layers['Affine2'].db
	
	return grads

O gradiente do parâmetro é obtido pelo método de retropropagação de erro (backpropagation)

Use este SimpleConvNet para aprender sobre o conjunto de dados MNIST. A taxa de reconhecimento dos dados de treinamento é de 99,82%, a taxa de reconhecimento dos dados de teste é de 98,96% e a taxa de reconhecimento dos dados de teste é de cerca de 99%, o que é uma taxa de reconhecimento muito alta para uma rede pequena.

おすすめ

転載: blog.csdn.net/loyd3/article/details/131339417