fashion-mnist训练集包含60000张图片,测试集包含10000张图片,图片格式都是28*28的灰度图,总共包含10个类别。它是对于传统mnist数据集的代替。CNN在传统的mnist上可以达到99.7%的准确率,mnist过于简单和完美了,并且无法代替所有的CV任务。
fashion-mnist数据集
from __future__ import absolute_import, division, print_function
import argparse
import logging
import os
import tensorflow as tf
from tensorflow import keras
from keras.callbacks import TensorBoard
import numpy as np
import matplotlib.pyplot as plt
import nni
LOG = logging.getLogger('basic_classification')
TENSORBOARD_DIR = os.environ['NNI_OUTPUT_DIR'] # '/media/ning/CE0AC1720AC157DB/basic_classification'
# import data
fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
# class names
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
train_images = np.expand_dims(train_images, -1).astype(np.float) / 255.0
test_images = np.expand_dims(test_images, -1).astype(np.float) / 255.0
train_labels = keras.utils.to_categorical(train_labels, 10)
test_labels = keras.utils.to_categorical(test_labels, 10)
def create_mnist_model(hyper_params):
layers = [
keras.layers.Flatten(input_shape=(28, 28, 1)),
keras.layers.Dense(128, activation=tf.nn.relu),
keras.layers.Dense(10, activation=tf.nn.softmax)
]
model = keras.Sequential(layers)
if hyper_params['optimizer'] == 'Adam':
optimizer = keras.optimizers.Adam(lr=hyper_params['learning_rate'])
elif hyper_params['optimizer'] == 'SGD':
optimizer = keras.optimizers.SGD(lr=hyper_params['learning_rate'], momentum=0.9)
elif hyper_params['optimizer'] == 'Adadelta':
optimizer = keras.optimizers.Adadelta(lr=hyper_params['learning_rate'], rho=0.95, epsilon=None, decay=0.0)
elif hyper_params['optimizer'] == 'Adagrad':
optimizer = keras.optimizers.Adagrad(lr=hyper_params['learning_rate'], epsilon=None, decay=0.0)
model.compile(loss=keras.losses.categorical_crossentropy, optimizer=optimizer, metrics=['accuracy'])
return model
def generate_default_params():
return {
'optimizer': 'Adam',
'learning_rate': 0.001
}
class SendMetrics(keras.callbacks.Callback):
def on_epoch_end(self, epoch, logs={}):
'''
Run on end of each epoch
'''
LOG.debug(logs)
nni.report_intermediate_result(logs["val_acc"])
def train(args, params):
model = create_mnist_model(params)
model.fit(train_images, train_labels, batch_size=args.batch_size, epochs=args.epochs, verbose=1,
validation_data=(test_images, test_labels), callbacks=[SendMetrics(), TensorBoard(log_dir=TENSORBOARD_DIR)])
_, acc = model.evaluate(test_images, test_labels, verbose=0)
LOG.debug('Final result is: %d', acc)
nni.report_final_result(acc)
if __name__ == '__main__':
PARSER = argparse.ArgumentParser()
PARSER.add_argument("--batch_size", type=int, default=200, help="batch size", required=False)
PARSER.add_argument("--epochs", type=int, default=10, help="Train epochs", required=False)
PARSER.add_argument("--num_train", type=int, default=60000, help="Number of train samples to be used, maximum 60000", required=False)
PARSER.add_argument("--num_test", type=int, default=10000, help="Number of test samples to be used, maximum 10000", required=False)
ARGS, UNKNOWN = PARSER.parse_known_args()
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
# get parameters from tuner
RECEIVED_PARAMS = nni.get_next_parameter()
LOG.debug(RECEIVED_PARAMS)
PARAMS = generate_default_params()
PARAMS.update(RECEIVED_PARAMS)
# train
train(ARGS, PARAMS)
这段代码是执行的主程序,主要注意以下几个部分。这几部分也就是在一个python程序中嵌入nni需要修改的地方。
RECEIVED_PARAMS = nni.get_next_parameter()
PARAMS.update(RECEIVED_PARAMS)
# 在SendMetrics类中on_epoch_end函数:
nni.report_intermediate_result(logs["val_acc"])
# 在train函数中
nni.report_final_result(acc)
{
"optimizer":{"_type":"choice","_value":["Adam", "SGD", "Adadelta", "Adagrad"]},
"learning_rate":{"_type":"choice","_value":[0.0001, 0.001, 0.002, 0.005]}
}
这里使用了不同种类的优化器和不同的学习率。
choice指的是从中选择,还有其他许多种情况,具体可以参见文档
search space
authorName: default
experimentName: fashion-mnist
trialConcurrency: 1
maxExecDuration: 1h
maxTrialNum: 15
#choice: local, remote, pai
trainingServicePlatform: local
searchSpacePath: search_space.json
#choice: true, false
useAnnotation: false
tuner:
#choice: TPE, Random, Anneal, Evolution, BatchTuner
#SMAC (SMAC should be installed through nnictl)
builtinTunerName: TPE
classArgs:
#choice: maximize, minimize
optimize_mode: maximize
trial:
command: python3 basic_classification.py
codeDir: .
gpuNum: 0
具体内容可以参考文档,重点强调一下以下几个:
@nni.variable(nni.choice(option1,option2,...,optionN),name=variable)
形式,具体见文档config.yml reference
nnictl create --config config.yml
webUI
从结果中可以看出,使用adam优化器和0.002的学习率可以达到0.8818的准确率
nnictl log stdder
,或者打开log查看出错信息,一般是在/home/directory/nni/experiments/实验ID/trial/每组参数实验id
下的stdder中