《PaddlePaddle从入门到炼丹》十——VisulDL训练可视化

时间:2019-01-18
本文章向大家介绍《PaddlePaddle从入门到炼丹》十——VisulDL训练可视化,主要包括《PaddlePaddle从入门到炼丹》十——VisulDL训练可视化使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

先这样看着,之后有时间再详细介绍,目前凑合着看

import paddle as paddle
import paddle.dataset.cifar as cifar
import paddle.fluid as fluid
import mobilenet_v2
from visualdl import LogWriter
# 创建记录器
log_writer = LogWriter(dir='log/', sync_cycle=10)

# 创建训练和测试记录数据工具
with log_writer.mode('train') as writer:
    train_cost_writer = writer.scalar('cost')
    train_acc_writer = writer.scalar('accuracy')
    histogram = writer.histogram('histogram', num_buckets=50)

with log_writer.mode('test') as writer:
    test_cost_writer = writer.scalar('cost')
    test_acc_writer = writer.scalar('accuracy')
def conv_bn_layer(input, filter_size, num_filters, stride, padding, num_groups=1, if_act=True, use_cudnn=True):
    conv = fluid.layers.conv2d(input=input,
                               num_filters=num_filters,
                               filter_size=filter_size,
                               stride=stride,
                               padding=padding,
                               groups=num_groups,
                               use_cudnn=use_cudnn,
                               bias_attr=False)
    bn = fluid.layers.batch_norm(input=conv)
    if if_act:
        return fluid.layers.relu6(bn)
    else:
        return bn


def shortcut(input, data_residual):
    return fluid.layers.elementwise_add(input, data_residual)


def inverted_residual_unit(input,
                           num_in_filter,
                           num_filters,
                           ifshortcut,
                           stride,
                           filter_size,
                           padding,
                           expansion_factor):
    num_expfilter = int(round(num_in_filter * expansion_factor))

    channel_expand = conv_bn_layer(input=input,
                                   num_filters=num_expfilter,
                                   filter_size=1,
                                   stride=1,
                                   padding=0,
                                   num_groups=1,
                                   if_act=True)

    bottleneck_conv = conv_bn_layer(input=channel_expand,
                                    num_filters=num_expfilter,
                                    filter_size=filter_size,
                                    stride=stride,
                                    padding=padding,
                                    num_groups=num_expfilter,
                                    if_act=True,
                                    use_cudnn=False)

    linear_out = conv_bn_layer(input=bottleneck_conv,
                               num_filters=num_filters,
                               filter_size=1,
                               stride=1,
                               padding=0,
                               num_groups=1,
                               if_act=False)
    if ifshortcut:
        out = shortcut(input=input, data_residual=linear_out)
        return out
    else:
        return linear_out


def invresi_blocks(input, in_c, t, c, n, s, name=None):
    first_block = inverted_residual_unit(input=input,
                                         num_in_filter=in_c,
                                         num_filters=c,
                                         ifshortcut=False,
                                         stride=s,
                                         filter_size=3,
                                         padding=1,
                                         expansion_factor=t)

    last_residual_block = first_block
    last_c = c

    for i in range(1, n):
        last_residual_block = inverted_residual_unit(input=last_residual_block,
                                                     num_in_filter=last_c,
                                                     num_filters=c,
                                                     ifshortcut=True,
                                                     stride=1,
                                                     filter_size=3,
                                                     padding=1,
                                                     expansion_factor=t)
    return last_residual_block


def net(input, class_dim, scale=1.0):
    bottleneck_params_list = [
        (1, 16, 1, 1),
        (6, 24, 2, 2),
        (6, 32, 3, 2),
        (6, 64, 4, 2),
        (6, 96, 3, 1),
        (6, 160, 3, 2),
        (6, 320, 1, 1),
    ]

    # conv1
    input = conv_bn_layer(input,
                          num_filters=int(32 * scale),
                          filter_size=3,
                          stride=2,
                          padding=1,
                          if_act=True)

    # bottleneck sequences
    i = 1
    in_c = int(32 * scale)
    for layer_setting in bottleneck_params_list:
        t, c, n, s = layer_setting
        i += 1
        input = invresi_blocks(input=input,
                               in_c=in_c,
                               t=t,
                               c=int(c * scale),
                               n=n,
                               s=s,
                               name='conv' + str(i))
        in_c = int(c * scale)
    # last_conv
    input = conv_bn_layer(input=input,
                          num_filters=int(1280 * scale) if scale > 1.0 else 1280,
                          filter_size=1,
                          stride=1,
                          padding=0,
                          if_act=True)

    feature = fluid.layers.pool2d(input=input,
                                  pool_size=7,
                                  pool_stride=1,
                                  pool_type='avg',
                                  global_pooling=True)
    net = fluid.layers.fc(input=feature,
                          size=class_dim,
                          act='softmax')
    return net
# 定义输入层
image = fluid.layers.data(name='image', shape=[3, 32, 32], dtype='float32')
label = fluid.layers.data(name='label', shape=[1], dtype='int64')

# 获取分类器
model = net(image, 10)

# 获取损失函数和准确率函数
cost = fluid.layers.cross_entropy(input=model, label=label)
avg_cost = fluid.layers.mean(cost)
acc = fluid.layers.accuracy(input=model, label=label)

# 获取训练和测试程序
test_program = fluid.default_main_program().clone(for_test=True)

# 定义优化方法
optimizer = fluid.optimizer.AdamOptimizer(learning_rate=1e-3)
opts = optimizer.minimize(avg_cost)

# 获取MNIST数据
train_reader = paddle.batch(cifar.train10(), batch_size=32)
test_reader = paddle.batch(cifar.test10(), batch_size=32)

# 定义一个使用CPU的解析器
place = fluid.CUDAPlace(0)
# place = fluid.CPUPlace()
exe = fluid.Executor(place)
# 进行参数初始化
exe.run(fluid.default_startup_program())

# 定义输入数据维度
feeder = fluid.DataFeeder(place=place, feed_list=[image, label])
# 定义日志的开始位置和获取参数名称
train_step = 0
test_step = 0
params_name = fluid.default_startup_program().global_block().all_parameters()[0].name
# 训练10次
for pass_id in range(10):
    # 进行训练
    for batch_id, data in enumerate(train_reader()):
        train_cost, train_acc, params = exe.run(program=fluid.default_main_program(),
                                                feed=feeder.feed(data),
                                                fetch_list=[avg_cost, acc, params_name])
        # 保存训练的日志数据
        train_step += 1
        train_cost_writer.add_record(train_step, train_cost[0])
        train_acc_writer.add_record(train_step, train_acc[0])
        histogram.add_record(train_step, params.flatten())

        # 每100个batch打印一次信息
        if batch_id % 100 == 0:
            print('Pass:%d, Batch:%d, Cost:%0.5f, Accuracy:%0.5f' %
                  (pass_id, batch_id, train_cost[0], train_acc[0]))

    # 进行测试
    test_accs = []
    test_costs = []
    for batch_id, data in enumerate(test_reader()):
        test_cost, test_acc = exe.run(program=test_program,
                                      feed=feeder.feed(data),
                                      fetch_list=[avg_cost, acc])
        # 保存测试的日志数据
        test_step += 1
        test_cost_writer.add_record(test_step, test_cost[0])
        test_acc_writer.add_record(test_step, test_acc[0])

        test_accs.append(test_acc[0])
        test_costs.append(test_cost[0])
    # 求测试结果的平均值
    test_cost = (sum(test_costs) / len(test_costs))
    test_acc = (sum(test_accs) / len(test_accs))
    print('Test:%d, Cost:%0.5f, Accuracy:%0.5f' % (pass_id, test_cost, test_acc))