forked from chainer/chainer
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
170 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#!/usr/bin/env python | ||
|
||
from chainer import cuda, Variable | ||
|
||
import numpy as np | ||
|
||
import bokeh.plotting as plotting | ||
from bokeh.models import GlyphRenderer | ||
|
||
|
||
class LiveMonitor(object): | ||
|
||
SLICE_UNIT = 500 | ||
|
||
def __init__(self, server='chainer', **kwargs): | ||
plotting.output_server(server) | ||
|
||
self.data = {} | ||
|
||
self.train_loss = self._initialize_figure(title='Train loss', color='#FF0000', **kwargs) | ||
self.train_acc = self._initialize_figure(title='Train accuracy', color='#0000FF', **kwargs) | ||
self.test_loss = self._initialize_figure(title='Test loss', color='#FF0000', **kwargs) | ||
self.test_acc = self._initialize_figure(title='Test accuracy', color='#0000FF', **kwargs) | ||
|
||
self.grid = plotting.gridplot([[self.train_loss, self.test_loss], | ||
[self.train_acc, self.test_acc]]) | ||
|
||
plotting.show(self.grid) | ||
|
||
def _initialize_figure(self, color=None, line_width=2, | ||
title=None, title_text_font_size='9pt', | ||
plot_width=400, plot_height=280): | ||
figure = plotting.figure(title=title, title_text_font_size=title_text_font_size, | ||
plot_width=plot_width, plot_height=plot_height) | ||
x = np.array([]) | ||
y = np.array([]) | ||
self.data[figure.title] = y | ||
figure.line(x, y, color=color, line_width=line_width) | ||
return figure | ||
|
||
def _maybe_update(self, figure, value): | ||
if value is not None: | ||
if isinstance(value, Variable): | ||
value = cuda.to_cpu(value.data) | ||
renderer = figure.select(dict(type=GlyphRenderer)) | ||
ds = renderer[0].data_source | ||
|
||
y = np.append(self.data[figure.title], value) | ||
self.data[figure.title] = y | ||
length = len(y) | ||
x = np.arange(length) | ||
if length > self.SLICE_UNIT: | ||
step = length // self.SLICE_UNIT | ||
y = y[::step] | ||
x = x[::step] | ||
ds.data['y'] = y | ||
ds.data['x'] = x | ||
plotting.cursession().store_objects(ds) | ||
|
||
def update(self, train_loss=None, train_accuracy=None, | ||
test_loss=None, test_accuracy=None): | ||
self._maybe_update(self.train_loss, train_loss) | ||
self._maybe_update(self.train_acc, train_accuracy) | ||
self._maybe_update(self.test_loss, test_loss) | ||
self._maybe_update(self.test_acc, test_accuracy) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
#!/usr/bin/env python | ||
"""Chainer example: train a multi-layer perceptron on MNIST | ||
This is a minimal example to write a feed-forward net. It requires scikit-learn | ||
to load MNIST dataset. | ||
""" | ||
import argparse | ||
import numpy as np | ||
from sklearn.datasets import fetch_mldata | ||
from chainer import cuda, Variable, FunctionSet, optimizers | ||
import chainer.functions as F | ||
|
||
parser = argparse.ArgumentParser(description='Chainer example: MNIST') | ||
parser.add_argument('--gpu', '-g', default=-1, type=int, | ||
help='GPU ID (negative value indicates CPU)') | ||
args = parser.parse_args() | ||
|
||
batchsize = 100 | ||
n_epoch = 20 | ||
n_units = 1000 | ||
|
||
# Prepare dataset | ||
print 'fetch MNIST dataset' | ||
mnist = fetch_mldata('MNIST original') | ||
mnist.data = mnist.data.astype(np.float32) | ||
mnist.data /= 255 | ||
mnist.target = mnist.target.astype(np.int32) | ||
|
||
N = 60000 | ||
x_train, x_test = np.split(mnist.data, [N]) | ||
y_train, y_test = np.split(mnist.target, [N]) | ||
N_test = y_test.size | ||
|
||
# Prepare multi-layer perceptron model | ||
model = FunctionSet(l1=F.Linear(784, n_units), | ||
l2=F.Linear(n_units, n_units), | ||
l3=F.Linear(n_units, 10)) | ||
if args.gpu >= 0: | ||
cuda.init(args.gpu) | ||
model.to_gpu() | ||
|
||
# Neural net architecture | ||
def forward(x_data, y_data, train=True): | ||
x, t = Variable(x_data), Variable(y_data) | ||
h1 = F.dropout(F.relu(model.l1(x)), train=train) | ||
h2 = F.dropout(F.relu(model.l2(h1)), train=train) | ||
y = model.l3(h2) | ||
return F.softmax_cross_entropy(y, t), F.accuracy(y, t) | ||
|
||
# Setup optimizer | ||
optimizer = optimizers.Adam() | ||
optimizer.setup(model.collect_parameters()) | ||
|
||
# Live monitoring | ||
from chainer.sandbox.plotting import LiveMonitor | ||
monitor = LiveMonitor() | ||
|
||
# Learning loop | ||
for epoch in xrange(1, n_epoch+1): | ||
print 'epoch', epoch | ||
|
||
# training | ||
perm = np.random.permutation(N) | ||
sum_accuracy = 0 | ||
sum_loss = 0 | ||
for i in xrange(0, N, batchsize): | ||
x_batch = x_train[perm[i:i+batchsize]] | ||
y_batch = y_train[perm[i:i+batchsize]] | ||
if args.gpu >= 0: | ||
x_batch = cuda.to_gpu(x_batch) | ||
y_batch = cuda.to_gpu(y_batch) | ||
|
||
optimizer.zero_grads() | ||
loss, acc = forward(x_batch, y_batch) | ||
loss.backward() | ||
optimizer.update() | ||
|
||
monitor.update(train_loss=loss, train_accuracy=acc) | ||
|
||
sum_loss += float(cuda.to_cpu(loss.data)) * batchsize | ||
sum_accuracy += float(cuda.to_cpu(acc.data)) * batchsize | ||
|
||
print 'train mean loss={}, accuracy={}'.format( | ||
sum_loss / N, sum_accuracy / N) | ||
|
||
# evaluation | ||
sum_accuracy = 0 | ||
sum_loss = 0 | ||
for i in xrange(0, N_test, batchsize): | ||
x_batch = x_test[i:i+batchsize] | ||
y_batch = y_test[i:i+batchsize] | ||
if args.gpu >= 0: | ||
x_batch = cuda.to_gpu(x_batch) | ||
y_batch = cuda.to_gpu(y_batch) | ||
|
||
loss, acc = forward(x_batch, y_batch, train=False) | ||
|
||
monitor.update(test_loss=loss, test_accuracy=acc) | ||
|
||
sum_loss += float(cuda.to_cpu(loss.data)) * batchsize | ||
sum_accuracy += float(cuda.to_cpu(acc.data)) * batchsize | ||
|
||
print 'test mean loss={}, accuracy={}'.format( | ||
sum_loss / N_test, sum_accuracy / N_test) |