手写数字识别问题:维数错误
Handwritten Digit Recognition Problem: Wrong number of dimensions
我正在尝试训练我的神经网络模型来识别手写数字,但我卡住了。
我面临的问题是,当我尝试训练我的神经网络时,我试图将我的训练数据传递给该函数,但是当我这样做时,我得到了维数错误的错误。
我的代码:
import theano
import lasagne as lse
import theano.tensor as T
def build_nn(input_var=None):
l_input=lse.layers.InputLayer(shape=(None,1,28,28),input_var=input_var)
ldrop=lse.layers.DropoutLayer(l_input,p=0.2)
l_hid1=lse.layers.DenseLayer(ldrop,num_units=800,
nonlinearity=lse.nonlinearities.rectify,
W=lse.init.GlorotUniform())
l_hid1_drop=lse.layers.DropoutLayer(l_hid1,p=0.5)
l_hid2=lse.layers.DenseLayer(l_hid1_drop,num_units=800,
nonlinearity=lse.nonlinearities.rectify,
W=lse.init.GlorotUniform())
l_hid2_drop=lse.layers.DropoutLayer(l_hid2,p=0.5)
l_output=lse.layers.DenseLayer(l_hid2_drop,num_units=10,nonlinearity=lse.nonlinearities.softmax)
return l_output
input_var=T.tensor4('inputs')
target_var=T.lvector('targets')
network=build_nn(input_var)
prediction=lse.layers.get_output(network)
loss=lse.objectives.categorical_crossentropy(prediction,target_var)
loss=loss.mean()
params=lse.layers.get_all_params(network,trainable=True)
update=lse.updates.nesterov_momentum(loss,params,learning_rate=1,momentum=0.9)
tain_fn=theano.function([input_var,target_var],loss,updates=update)
num_training_step=1000
for steps in range(num_training_step):
train_err=tain_fn(x_train,y_train)
print('Step '+str(steps))
错误:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-33-2827076f729d> in <module>
2
3 for steps in range(num_training_step):
----> 4 train_err=tain_fn(x_train,y_train)
5 print('Step '+str(steps))
~\Anaconda3\lib\site-packages\theano\compile\function_module.py in __call__(self, *args, **kwargs)
811 s.storage[0] = s.type.filter(
812 arg, strict=s.strict,
--> 813 allow_downcast=s.allow_downcast)
814
815 except Exception as e:
~\Anaconda3\lib\site-packages\theano\tensor\type.py in filter(self, data, strict, allow_downcast)
176 raise TypeError("Wrong number of dimensions: expected %s,"
177 " got %s with shape %s." % (self.ndim, data.ndim,
--> 178 data.shape))
179 if not data.flags.aligned:
180 try:
TypeError: Bad input argument to theano function with name "<ipython-input-32-e01e77ca594c>:14" at index 0 (0-based).
Backtrace when that variable is created:
File "C:\Users\hp\Anaconda3\lib\site-packages\ipykernel\zmqshell.py", line 536, in run_cell
return super(ZMQInteractiveShell, self).run_cell(*args, **kwargs)
File "C:\Users\hp\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2819, in run_cell
raw_cell, store_history, silent, shell_futures)
File "C:\Users\hp\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2845, in _run_cell
return runner(coro)
File "C:\Users\hp\Anaconda3\lib\site-packages\IPython\core\async_helpers.py", line 67, in _pseudo_sync_runner
coro.send(None)
File "C:\Users\hp\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 3020, in run_cell_async
interactivity=interactivity, compiler=compiler, result=result)
File "C:\Users\hp\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 3185, in run_ast_nodes
if (yield from self.run_code(code, result)):
File "C:\Users\hp\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 3267, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-32-e01e77ca594c>", line 1, in <module>
input_var=T.tensor4('inputs')
Wrong number of dimensions: expected 4, got 3 with shape (60000, 28, 28).
根据您的代码,您希望输入张量的形状为 (X, 1, 28, 28)
l_input=lse.layers.InputLayer(shape=(None,1,28,28),input_var=input_var)
其中 1 是通道数。如果您计划只使用一个通道(灰度),您可以将输入重构为 shape=(None,28,28),或者将数据重构为具有额外维度以适应输入层。
您的代码有两个问题:
- 您正在使用
l_input
as (batch_size, n_channels, height, width), x_train
as (batch_size, 高度, 宽度)。将 l_input
更改为 (batch_size, height, width),正如@Platon Pilton 建议的那样。
- 修复 1 后,您将得到另一个错误:
DenseLayer
expects input of shape (batch, n_dimensions)。为此,您需要重塑 x_train
形状 (batch, height*width):
l_input = lse.layers.InputLayer(shape=(None, 28, 28),input_var=input_var)
l_reshape = lse.layers.ReshapeLayer(l_input, ((None, 28*28))
ldrop=lse.layers.DropoutLayer(l_reshape, p=0.2)
# etc...
我正在尝试训练我的神经网络模型来识别手写数字,但我卡住了。
我面临的问题是,当我尝试训练我的神经网络时,我试图将我的训练数据传递给该函数,但是当我这样做时,我得到了维数错误的错误。
我的代码:
import theano
import lasagne as lse
import theano.tensor as T
def build_nn(input_var=None):
l_input=lse.layers.InputLayer(shape=(None,1,28,28),input_var=input_var)
ldrop=lse.layers.DropoutLayer(l_input,p=0.2)
l_hid1=lse.layers.DenseLayer(ldrop,num_units=800,
nonlinearity=lse.nonlinearities.rectify,
W=lse.init.GlorotUniform())
l_hid1_drop=lse.layers.DropoutLayer(l_hid1,p=0.5)
l_hid2=lse.layers.DenseLayer(l_hid1_drop,num_units=800,
nonlinearity=lse.nonlinearities.rectify,
W=lse.init.GlorotUniform())
l_hid2_drop=lse.layers.DropoutLayer(l_hid2,p=0.5)
l_output=lse.layers.DenseLayer(l_hid2_drop,num_units=10,nonlinearity=lse.nonlinearities.softmax)
return l_output
input_var=T.tensor4('inputs')
target_var=T.lvector('targets')
network=build_nn(input_var)
prediction=lse.layers.get_output(network)
loss=lse.objectives.categorical_crossentropy(prediction,target_var)
loss=loss.mean()
params=lse.layers.get_all_params(network,trainable=True)
update=lse.updates.nesterov_momentum(loss,params,learning_rate=1,momentum=0.9)
tain_fn=theano.function([input_var,target_var],loss,updates=update)
num_training_step=1000
for steps in range(num_training_step):
train_err=tain_fn(x_train,y_train)
print('Step '+str(steps))
错误:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-33-2827076f729d> in <module>
2
3 for steps in range(num_training_step):
----> 4 train_err=tain_fn(x_train,y_train)
5 print('Step '+str(steps))
~\Anaconda3\lib\site-packages\theano\compile\function_module.py in __call__(self, *args, **kwargs)
811 s.storage[0] = s.type.filter(
812 arg, strict=s.strict,
--> 813 allow_downcast=s.allow_downcast)
814
815 except Exception as e:
~\Anaconda3\lib\site-packages\theano\tensor\type.py in filter(self, data, strict, allow_downcast)
176 raise TypeError("Wrong number of dimensions: expected %s,"
177 " got %s with shape %s." % (self.ndim, data.ndim,
--> 178 data.shape))
179 if not data.flags.aligned:
180 try:
TypeError: Bad input argument to theano function with name "<ipython-input-32-e01e77ca594c>:14" at index 0 (0-based).
Backtrace when that variable is created:
File "C:\Users\hp\Anaconda3\lib\site-packages\ipykernel\zmqshell.py", line 536, in run_cell
return super(ZMQInteractiveShell, self).run_cell(*args, **kwargs)
File "C:\Users\hp\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2819, in run_cell
raw_cell, store_history, silent, shell_futures)
File "C:\Users\hp\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2845, in _run_cell
return runner(coro)
File "C:\Users\hp\Anaconda3\lib\site-packages\IPython\core\async_helpers.py", line 67, in _pseudo_sync_runner
coro.send(None)
File "C:\Users\hp\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 3020, in run_cell_async
interactivity=interactivity, compiler=compiler, result=result)
File "C:\Users\hp\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 3185, in run_ast_nodes
if (yield from self.run_code(code, result)):
File "C:\Users\hp\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 3267, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-32-e01e77ca594c>", line 1, in <module>
input_var=T.tensor4('inputs')
Wrong number of dimensions: expected 4, got 3 with shape (60000, 28, 28).
根据您的代码,您希望输入张量的形状为 (X, 1, 28, 28)
l_input=lse.layers.InputLayer(shape=(None,1,28,28),input_var=input_var)
其中 1 是通道数。如果您计划只使用一个通道(灰度),您可以将输入重构为 shape=(None,28,28),或者将数据重构为具有额外维度以适应输入层。
您的代码有两个问题:
- 您正在使用
l_input
as (batch_size, n_channels, height, width),x_train
as (batch_size, 高度, 宽度)。将l_input
更改为 (batch_size, height, width),正如@Platon Pilton 建议的那样。 - 修复 1 后,您将得到另一个错误:
DenseLayer
expects input of shape (batch, n_dimensions)。为此,您需要重塑x_train
形状 (batch, height*width):
l_input = lse.layers.InputLayer(shape=(None, 28, 28),input_var=input_var)
l_reshape = lse.layers.ReshapeLayer(l_input, ((None, 28*28))
ldrop=lse.layers.DropoutLayer(l_reshape, p=0.2)
# etc...