機械学習初学者です。Chainerを用いて固定サイズの画像を学習させるため、サンプルのimagenet内のtrain_imagenet.pyとalex.pyをもとにコードを書いたのですがエラーを吐きました。
以下、ソースコードとエラー文です。
#!/usr/bin/env python
"""Example code of learning a large scale convnet from ILSVRC2012 dataset.
Prerequisite: To run this example, crop the center of ILSVRC2012 training and
validation images, scale them to 256x256 and convert them to RGB, and make
two lists of space-separated CSV whose first column is full path to image and
second column is zero-origin label (this format is same as that used by Caffe's
ImageDataLayer).
"""
import argparse
import random
import numpy as np
import chainer
from chainer import training
from chainer.training import extensions
import alex
import googlenet
import googlenetbn
import nin
import resnet50
count = 0
class PreprocessedDataset(chainer.dataset.DatasetMixin):
def __init__(self, path, root, mean, crop_size_x, crop_size_y, random=True):
self.base = chainer.datasets.LabeledImageDataset(path, root)
self.mean = mean.astype(np.float32)
self.crop_size_x = crop_size_x
self.crop_size_y = crop_size_y
self.random = random
def __len__(self):
return len(self.base)
def get_example(self, i):
global count
#print(count)
count = count+1
# It reads the i-th image/label pair and return a preprocessed image.
# It applies following preprocesses:
# - Cropping (random or center rectangular)
# - Random flip
# - Scaling to [0, 1] value
#crop_size = self.crop_size
crop_size_x = self.crop_size_x
crop_size_y = self.crop_size_y
image, label = self.base[i]
_, h, w = image.shape
print(_,h,w)
#if h != crop_size_y:
#image = image[:, 0:h, :]
#if w != crop_size_x:
image -= self.mean[:, 0:crop_size_y, 0:crop_size_x]
image *= (1.0 / 255.0) # Scale to [0, 1]
return image, label
"""
if self.random:
# Randomly crop a region and flip the image
top = random.randint(0, h - crop_size_y - 1)
left = random.randint(0, w - crop_size_x - 1)
if random.randint(0, 1):
image = image[:, :, ::-1]
else:
# Crop the center
top = (h - crop_size_y) // 2
left = (w - crop_size_x) // 2
bottom = top + crop_size_y
right = left + crop_size_x
image = image[:, top:bottom, left:right]
image -= self.mean[:, top:bottom, left:right]
image *= (1.0 / 255.0) # Scale to [0, 1]
return image, label
"""
def main():
archs = {
'alex': alex.Alex,
'alex_fp16': alex.AlexFp16,
'googlenet': googlenet.GoogLeNet,
'googlenetbn': googlenetbn.GoogLeNetBN,
'googlenetbn_fp16': googlenetbn.GoogLeNetBNFp16,
'nin': nin.NIN,
'resnet50': resnet50.ResNet50,
'resnext50': resnet50.ResNeXt50,
}
parser = argparse.ArgumentParser(
description='Learning convnet from ILSVRC2012 dataset')
parser.add_argument('train', help='Path to training image-label list file')
parser.add_argument('val', help='Path to validation image-label list file')
parser.add_argument('--arch', '-a', choices=archs.keys(), default='nin',
help='Convnet architecture')
parser.add_argument('--batchsize', '-B', type=int, default=32,
help='Learning minibatch size')
parser.add_argument('--epoch', '-E', type=int, default=5,
help='Number of epochs to train')
parser.add_argument('--gpu', '-g', type=int, default=0,
help='GPU ID (negative value indicates CPU')
parser.add_argument('--initmodel',
help='Initialize the model from given file')
parser.add_argument('--loaderjob', '-j', type=int,
help='Number of parallel data loading processes')
parser.add_argument('--mean', '-m', default='mean.npy',
help='Mean file (computed by compute_mean.py)')
parser.add_argument('--resume', '-r', default='',
help='Initialize the trainer from given file')
parser.add_argument('--out', '-o', default='result',
help='Output directory')
parser.add_argument('--root', '-R', default='images/',
help='Root directory path of image files')
parser.add_argument('--val_batchsize', '-b', type=int, default=250,
help='Validation minibatch size')
parser.add_argument('--test', action='store_true')
parser.set_defaults(test=False)
args = parser.parse_args()
# Initialize the model to train
model = archs[args.arch]()
if args.initmodel:
print('Load model from {}'.format(args.initmodel))
chainer.serializers.load_npz(args.initmodel, model)
if args.gpu >= 0:
chainer.backends.cuda.get_device_from_id(
args.gpu).use() # Make the GPU current
model.to_gpu()
# Load the datasets and mean file
mean = np.load(args.mean)
train = PreprocessedDataset(args.train, args.root, mean, model.insize_x, model.insize_y)
val = PreprocessedDataset(args.val, args.root, mean, model.insize_x,model.insize_y, False)
# These iterators load the images with subprocesses running in parallel to
# the training/validation.
train_iter = chainer.iterators.MultiprocessIterator(
train, args.batchsize, n_processes=args.loaderjob)
val_iter = chainer.iterators.MultiprocessIterator(
val, args.val_batchsize, repeat=False, n_processes=args.loaderjob)
# Set up an optimizer
optimizer = chainer.optimizers.MomentumSGD(lr=0.01, momentum=0.9)
optimizer.setup(model)
# Set up a trainer
updater = training.StandardUpdater(
train_iter, optimizer, device=args.gpu)
trainer = training.Trainer(updater, (args.epoch, 'epoch'), args.out)
val_interval = (1 if args.test else 100000), 'iteration'
log_interval = (1 if args.test else 1000), 'iteration'
trainer.extend(extensions.Evaluator(val_iter, model, device=args.gpu),
trigger=val_interval)
trainer.extend(extensions.dump_graph('main/loss'))
trainer.extend(extensions.snapshot(), trigger=val_interval)
trainer.extend(extensions.snapshot_object(
model, 'model_iter_{.updater.iteration}'), trigger=val_interval)
# Be careful to pass the interval directly to LogReport
# (it determines when to emit log rather than when to read observations)
trainer.extend(extensions.LogReport(trigger=log_interval))
trainer.extend(extensions.observe_lr(), trigger=log_interval)
trainer.extend(extensions.PlotReport(['main/accuracy', 'main/loss'], x_key='epoch', file_name='main.png'))
trainer.extend(extensions.PlotReport(['validation/main/accuracy', 'validation/main/loss'], x_key='epoch', file_name='valid.png'))
trainer.extend(extensions.PrintReport([
'epoch', 'iteration', 'main/loss', 'validation/main/loss',
'main/accuracy', 'validation/main/accuracy', 'lr'
]), trigger=log_interval)
trainer.extend(extensions.ProgressBar(update_interval=10))
if args.resume:
chainer.serializers.load_npz(args.resume, trainer)
trainer.run()
chainer.serializers.save_npz('result/model_final', model)
chainer.serializers.save_npz('result/optimizer_final', optimizer)
if __name__ == '__main__':
main()
エラー文
Exception in main training loop: 'NoneType' object has no attribute 'dot'
Traceback (most recent call last):
File "/lib/python3.5/site-packages/chainer/training/trainer.py", line 306, in run
update()
File "/lib/python3.5/site-packages/chainer/training/updaters/standard_updater.py", line 149, in update
self.update_core()
File "/lib/python3.5/site-packages/chainer/training/updaters/standard_updater.py", line 160, in update_core
optimizer.update(loss_func, *in_arrays)
File "/lib/python3.5/site-packages/chainer/optimizer.py", line 645, in update
loss.backward(loss_scale=self._loss_scale)
File "/lib/python3.5/site-packages/chainer/variable.py", line 963, in backward
self._backward_main(retain_grad, loss_scale)
File "/lib/python3.5/site-packages/chainer/variable.py", line 1092, in _backward_main
target_input_indexes, out_grad, in_grad)
File "/lib/python3.5/site-packages/chainer/function_node.py", line 548, in backward_accumulate
gxs = self.backward(target_input_indexes, grad_outputs)
File "/lib/python3.5/site-packages/chainer/functions/connection/linear.py", line 80, in backward
gx, = LinearGradData().apply((W, gy))
File "/lib/python3.5/site-packages/chainer/function_node.py", line 258, in apply
outputs = self.forward(in_data)
File "/lib/python3.5/site-packages/chainer/functions/connection/linear.py", line 112, in forward
gx = gy.dot(W).astype(gy.dtype, copy=False)
Will finalize trainer extensions and updater before reraising the exception.
Traceback (most recent call last):
File "train_imagenet.py", line 187, in <module>
main()
File "train_imagenet.py", line 179, in main
trainer.run()
File "/lib/python3.5/site-packages/chainer/training/trainer.py", line 320, in run
six.reraise(*sys.exc_info())
File "/lib/python3.5/site-packages/six.py", line 693, in reraise
raise value
File "/lib/python3.5/site-packages/chainer/training/trainer.py", line 306, in run
update()
File "/lib/python3.5/site-packages/chainer/training/updaters/standard_updater.py", line 149, in update
self.update_core()
File "/lib/python3.5/site-packages/chainer/training/updaters/standard_updater.py", line 160, in update_core
optimizer.update(loss_func, *in_arrays)
File "/lib/python3.5/site-packages/chainer/optimizer.py", line 645, in update
loss.backward(loss_scale=self._loss_scale)
File "/lib/python3.5/site-packages/chainer/variable.py", line 963, in backward
self._backward_main(retain_grad, loss_scale)
File "/lib/python3.5/site-packages/chainer/variable.py", line 1092, in _backward_main
target_input_indexes, out_grad, in_grad)
File "/lib/python3.5/site-packages/chainer/function_node.py", line 548, in backward_accumulate
gxs = self.backward(target_input_indexes, grad_outputs)
File "/lib/python3.5/site-packages/chainer/functions/connection/linear.py", line 80, in backward
gx, = LinearGradData().apply((W, gy))
File "/lib/python3.5/site-packages/chainer/function_node.py", line 258, in apply
outputs = self.forward(in_data)
File "/lib/python3.5/site-packages/chainer/functions/connection/linear.py", line 112, in forward
gx = gy.dot(W).astype(gy.dtype, copy=False)
AttributeError: 'NoneType' object has no attribute 'dot'
ソースコードはtrain_imagenet.pyを、画像をクリッピングせずにそのまま学習に入力できるように書き換えました。
エラーの原因がわかるかたがいましたらよろしくお願い致します。