class CNN3_Model(ModelBase): u"""see: http://aidiary.hatenablog.com/entry/20151007/1444223445""" def __init__(self, input_size=32): super(CNN3_Model, self).__init__() # F.Convolution2D(in_channel, out_channel, filter_size) self.model = FunctionSet( # 1*32*32 -(conv)-> 20*28*28 -(pool)-> 20*14*14 conv1=F.Convolution2D(1, 20, 5), # 20*14*14 -(conv)-> 50*10*10 -(pool)-> 50*5*5=1250 conv2=F.Convolution2D(20, 50, 5), l1=F.Linear(1250, 300), l2=F.Linear(300, 2)) def forward(self, x_data, y_data, train=True): u"""return loss, accuracy""" x, t = Variable(x_data), Variable(y_data) h1 = F.max_pooling_2d(F.relu(self.model.conv1(x)), 2) h2 = F.max_pooling_2d(F.relu(self.model.conv2(h1)), 2) h3 = F.dropout(F.relu(self.model.l1(h2)), train=train) y = self.model.l2(h3) # 多クラス分類なので誤差関数としてソフトマックス関数の # 交差エントロピー関数を用いて、誤差を導出。最低でもlossは必要 return { "loss": F.softmax_cross_entropy(y, t), "accuracy": F.accuracy(y, t) }
class DQN_CNN(object): def __init__(self,n_act): N_output = n_act self.model = FunctionSet( conv1=F.Convolution2D(1, 16, 3, pad=1), conv2=F.Convolution2D(16, 16, 3, pad=1), l1=F.Linear(256, 256), l2=F.Linear(256, N_output)) def Q_func(self,x): N,h,w=x.shape x=x.reshape(N,1,h,w) x = Variable(x) h = F.relu(self.model.conv1(x)) h = F.max_pooling_2d(F.relu(self.model.conv2(h)), 2) h = F.relu(self.model.l1(h)) y = self.model.l2(h) return y
class CNN: file_names = None def __init__(self): self.optimizer = optimizers.Adam() self.model_name = "cnn_nantyara" if os.path.exists(self.model_name): self.load_model() else: self.crete_model() self.optimizer.setup(self.model.collect_parameters()) def crete_model(self): self.model = FunctionSet( conv1=F.Convolution2D(3, 32, 3), bn1=F.BatchNormalization(32), conv2=F.Convolution2D(32, 64, 3, pad=1), bn2=F.BatchNormalization(64), conv3=F.Convolution2D(64, 64, 3, pad=1), fl4=F.Linear(1024, 256), fl5=F.Linear(256, 2), ) def get_data(self, ifpath, image_categories, reshape_size=(3, 32, 32)): x = [] x_apd = x.append y = [] y_apd = y.append for i_category, category in enumerate(image_categories): for i_num in xrange(1, self.get_num_of_images(ifpath, category)): image = np.array(Image.open(ifpath + "/" + category + str(i_num) + ".jpeg"), dtype=np.float32).reshape( reshape_size ) x_apd(image) y_apd(i_category) self.N = len(x) return x, np.array(y, dtype=np.int32) def get_data_for_predict(self, ifpath, image_name, reshape_size=(3, 32, 32)): image = np.array(Image.open(ifpath + "/" + image_name), dtype=np.float32) image = cv2.resize(image, (reshape_size[1], reshape_size[2])) # print image.shape image = image.reshape(reshape_size) return [image] def forward(self, x_data, y_data, train=True): x, t = Variable(np.array(x_data)), Variable(y_data) h1 = F.max_pooling_2d(F.relu(self.model.bn1(self.model.conv1(x))), 2) h2 = F.max_pooling_2d(F.relu(self.model.bn2(self.model.conv2(h1))), 2) h3 = F.max_pooling_2d(F.relu(self.model.conv3(h2)), 2) h4 = F.dropout(F.relu(self.model.fl4(h3)), train=train) y = self.model.fl5(h4) if train: return F.softmax_cross_entropy(y, t), F.accuracy(y, t) else: res = [d for data in F.softmax(y).data for d in data] # print res return np.array(res).argmax() if len([r for r in res if r > 0.5]) > 0 else "unknown" def get_num_of_images(self, path, image_name): cmd = "ls images|grep %s|wc -l" % (image_name) return int(subprocess.check_output(cmd, shell=True)) def dump_model(self): self.model.to_cpu() with open(self.model_name, "wb") as f: pickle.dump(self.model, f, -1) def load_model(self): with open(self.model_name, "rb") as f: self.model = pickle.load(f) def fit(self, x_train, y_train, epoch=20, batchsize=100): for epoch in xrange(1, epoch + 1): print "epoch", epoch # training sum_accuracy = 0 sum_loss = 0 for i in xrange(0, self.N, batchsize): self.optimizer.zero_grads() loss, acc = self.forward(x_train[i : i + batchsize], y_train[i : i + batchsize]) loss.backward() self.optimizer.update() print "train mean loss=%s, accuracy =%s" % (str(loss.data), str(acc.data)) self.dump_model() def predict(self, x): y = self.forward(x, np.zeros(1, dtype=np.int32), train=False) sys.stdout.write(str(self.file_names[y]) if y != "unknonw" else "unknonw")