diff --git a/CNNs/MobileNet.py b/CNNs/MobileNet.py new file mode 100644 index 0000000..612a71b --- /dev/null +++ b/CNNs/MobileNet.py @@ -0,0 +1,169 @@ +""" +2017/11/24 ref:https://github.com/Zehaos/MobileNet/blob/master/nets/mobilenet.py +""" + +import tensorflow as tf +from tensorflow.python.training import moving_averages + +UPDATE_OPS_COLLECTION = "_update_ops_" + +# create variable +def create_variable(name, shape, initializer, + dtype=tf.float32, trainable=True): + return tf.get_variable(name, shape=shape, dtype=dtype, + initializer=initializer, trainable=trainable) + +# batchnorm layer +def bacthnorm(inputs, scope, epsilon=1e-05, momentum=0.99, is_training=True): + inputs_shape = inputs.get_shape().as_list() + params_shape = inputs_shape[-1:] + axis = list(range(len(inputs_shape) - 1)) + + with tf.variable_scope(scope): + beta = create_variable("beta", params_shape, + initializer=tf.zeros_initializer()) + gamma = create_variable("gamma", params_shape, + initializer=tf.ones_initializer()) + # for inference + moving_mean = create_variable("moving_mean", params_shape, + initializer=tf.zeros_initializer(), trainable=False) + moving_variance = create_variable("moving_variance", params_shape, + initializer=tf.ones_initializer(), trainable=False) + if is_training: + mean, variance = tf.nn.moments(inputs, axes=axis) + update_move_mean = moving_averages.assign_moving_average(moving_mean, + mean, decay=momentum) + update_move_variance = moving_averages.assign_moving_average(moving_variance, + variance, decay=momentum) + tf.add_to_collection(UPDATE_OPS_COLLECTION, update_move_mean) + tf.add_to_collection(UPDATE_OPS_COLLECTION, update_move_variance) + else: + mean, variance = moving_mean, moving_variance + return tf.nn.batch_normalization(inputs, mean, variance, beta, gamma, epsilon) + +# depthwise conv2d layer +def depthwise_conv2d(inputs, scope, filter_size=3, channel_multiplier=1, strides=1): + inputs_shape = inputs.get_shape().as_list() + in_channels = inputs_shape[-1] + with tf.variable_scope(scope): + filter = create_variable("filter", shape=[filter_size, filter_size, + in_channels, channel_multiplier], + initializer=tf.truncated_normal_initializer(stddev=0.01)) + + return tf.nn.depthwise_conv2d(inputs, filter, strides=[1, strides, strides, 1], + padding="SAME", rate=[1, 1]) + +# conv2d layer +def conv2d(inputs, scope, num_filters, filter_size=1, strides=1): + inputs_shape = inputs.get_shape().as_list() + in_channels = inputs_shape[-1] + with tf.variable_scope(scope): + filter = create_variable("filter", shape=[filter_size, filter_size, + in_channels, num_filters], + initializer=tf.truncated_normal_initializer(stddev=0.01)) + return tf.nn.conv2d(inputs, filter, strides=[1, strides, strides, 1], + padding="SAME") + +# avg pool layer +def avg_pool(inputs, pool_size, scope): + with tf.variable_scope(scope): + return tf.nn.avg_pool(inputs, [1, pool_size, pool_size, 1], + strides=[1, pool_size, pool_size, 1], padding="VALID") + +# fully connected layer +def fc(inputs, n_out, scope, use_bias=True): + inputs_shape = inputs.get_shape().as_list() + n_in = inputs_shape[-1] + with tf.variable_scope(scope): + weight = create_variable("weight", shape=[n_in, n_out], + initializer=tf.random_normal_initializer(stddev=0.01)) + if use_bias: + bias = create_variable("bias", shape=[n_out,], + initializer=tf.zeros_initializer()) + return tf.nn.xw_plus_b(inputs, weight, bias) + return tf.matmul(inputs, weight) + + +class MobileNet(object): + def __init__(self, inputs, num_classes=1000, is_training=True, + width_multiplier=1, scope="MobileNet"): + """ + The implement of MobileNet(ref:https://arxiv.org/abs/1704.04861) + :param inputs: 4-D Tensor of [batch_size, height, width, channels] + :param num_classes: number of classes + :param is_training: Boolean, whether or not the model is training + :param width_multiplier: float, controls the size of model + :param scope: Optional scope for variables + """ + self.inputs = inputs + self.num_classes = num_classes + self.is_training = is_training + self.width_multiplier = width_multiplier + + # construct model + with tf.variable_scope(scope): + # conv1 + net = conv2d(inputs, "conv_1", round(32 * width_multiplier), filter_size=3, + strides=2) # ->[N, 112, 112, 32] + net = tf.nn.relu(bacthnorm(net, "conv_1/bn", is_training=self.is_training)) + net = self._depthwise_separable_conv2d(net, 64, self.width_multiplier, + "ds_conv_2") # ->[N, 112, 112, 64] + net = self._depthwise_separable_conv2d(net, 128, self.width_multiplier, + "ds_conv_3", downsample=True) # ->[N, 56, 56, 128] + net = self._depthwise_separable_conv2d(net, 128, self.width_multiplier, + "ds_conv_4") # ->[N, 56, 56, 128] + net = self._depthwise_separable_conv2d(net, 256, self.width_multiplier, + "ds_conv_5", downsample=True) # ->[N, 28, 28, 256] + net = self._depthwise_separable_conv2d(net, 256, self.width_multiplier, + "ds_conv_6") # ->[N, 28, 28, 256] + net = self._depthwise_separable_conv2d(net, 512, self.width_multiplier, + "ds_conv_7", downsample=True) # ->[N, 14, 14, 512] + net = self._depthwise_separable_conv2d(net, 512, self.width_multiplier, + "ds_conv_8") # ->[N, 14, 14, 512] + net = self._depthwise_separable_conv2d(net, 512, self.width_multiplier, + "ds_conv_9") # ->[N, 14, 14, 512] + net = self._depthwise_separable_conv2d(net, 512, self.width_multiplier, + "ds_conv_10") # ->[N, 14, 14, 512] + net = self._depthwise_separable_conv2d(net, 512, self.width_multiplier, + "ds_conv_11") # ->[N, 14, 14, 512] + net = self._depthwise_separable_conv2d(net, 512, self.width_multiplier, + "ds_conv_12") # ->[N, 14, 14, 512] + net = self._depthwise_separable_conv2d(net, 1024, self.width_multiplier, + "ds_conv_13", downsample=True) # ->[N, 7, 7, 1024] + net = self._depthwise_separable_conv2d(net, 1024, self.width_multiplier, + "ds_conv_14") # ->[N, 7, 7, 1024] + net = avg_pool(net, 7, "avg_pool_15") + net = tf.squeeze(net, [1, 2], name="SpatialSqueeze") + self.logits = fc(net, self.num_classes, "fc_16") + self.predictions = tf.nn.softmax(self.logits) + + def _depthwise_separable_conv2d(self, inputs, num_filters, width_multiplier, + scope, downsample=False): + """depthwise separable convolution 2D function""" + num_filters = round(num_filters * width_multiplier) + strides = 2 if downsample else 1 + + with tf.variable_scope(scope): + # depthwise conv2d + dw_conv = depthwise_conv2d(inputs, "depthwise_conv", strides=strides) + # batchnorm + bn = bacthnorm(dw_conv, "dw_bn", is_training=self.is_training) + # relu + relu = tf.nn.relu(bn) + # pointwise conv2d (1x1) + pw_conv = conv2d(relu, "pointwise_conv", num_filters) + # bn + bn = bacthnorm(pw_conv, "pw_bn", is_training=self.is_training) + return tf.nn.relu(bn) + +if __name__ == "__main__": + # test data + inputs = tf.random_normal(shape=[4, 224, 224, 3]) + mobileNet = MobileNet(inputs) + writer = tf.summary.FileWriter("./logs", graph=tf.get_default_graph()) + init = tf.global_variables_initializer() + with tf.Session() as sess: + sess.run(init) + pred = sess.run(mobileNet.predictions) + print(pred.shape) + diff --git a/CNNs/ResNet50.py b/CNNs/ResNet50.py new file mode 100644 index 0000000..5f7d5d5 --- /dev/null +++ b/CNNs/ResNet50.py @@ -0,0 +1,143 @@ +""" +ResNet50 +2017/12/06 +""" + +import tensorflow as tf +from tensorflow.python.training import moving_averages + +fc_initializer = tf.contrib.layers.xavier_initializer +conv2d_initializer = tf.contrib.layers.xavier_initializer_conv2d + +# create weight variable +def create_var(name, shape, initializer, trainable=True): + return tf.get_variable(name, shape=shape, dtype=tf.float32, + initializer=initializer, trainable=trainable) + +# conv2d layer +def conv2d(x, num_outputs, kernel_size, stride=1, scope="conv2d"): + num_inputs = x.get_shape()[-1] + with tf.variable_scope(scope): + kernel = create_var("kernel", [kernel_size, kernel_size, + num_inputs, num_outputs], + conv2d_initializer()) + return tf.nn.conv2d(x, kernel, strides=[1, stride, stride, 1], + padding="SAME") + +# fully connected layer +def fc(x, num_outputs, scope="fc"): + num_inputs = x.get_shape()[-1] + with tf.variable_scope(scope): + weight = create_var("weight", [num_inputs, num_outputs], + fc_initializer()) + bias = create_var("bias", [num_outputs,], + tf.zeros_initializer()) + return tf.nn.xw_plus_b(x, weight, bias) + + +# batch norm layer +def batch_norm(x, decay=0.999, epsilon=1e-03, is_training=True, + scope="scope"): + x_shape = x.get_shape() + num_inputs = x_shape[-1] + reduce_dims = list(range(len(x_shape) - 1)) + with tf.variable_scope(scope): + beta = create_var("beta", [num_inputs,], + initializer=tf.zeros_initializer()) + gamma = create_var("gamma", [num_inputs,], + initializer=tf.ones_initializer()) + # for inference + moving_mean = create_var("moving_mean", [num_inputs,], + initializer=tf.zeros_initializer(), + trainable=False) + moving_variance = create_var("moving_variance", [num_inputs], + initializer=tf.ones_initializer(), + trainable=False) + if is_training: + mean, variance = tf.nn.moments(x, axes=reduce_dims) + update_move_mean = moving_averages.assign_moving_average(moving_mean, + mean, decay=decay) + update_move_variance = moving_averages.assign_moving_average(moving_variance, + variance, decay=decay) + tf.add_to_collection(tf.GraphKeys.UPDATE_OPS, update_move_mean) + tf.add_to_collection(tf.GraphKeys.UPDATE_OPS, update_move_variance) + else: + mean, variance = moving_mean, moving_variance + return tf.nn.batch_normalization(x, mean, variance, beta, gamma, epsilon) + + +# avg pool layer +def avg_pool(x, pool_size, scope): + with tf.variable_scope(scope): + return tf.nn.avg_pool(x, [1, pool_size, pool_size, 1], + strides=[1, pool_size, pool_size, 1], padding="VALID") + +# max pool layer +def max_pool(x, pool_size, stride, scope): + with tf.variable_scope(scope): + return tf.nn.max_pool(x, [1, pool_size, pool_size, 1], + [1, stride, stride, 1], padding="SAME") + +class ResNet50(object): + def __init__(self, inputs, num_classes=1000, is_training=True, + scope="resnet50"): + self.inputs =inputs + self.is_training = is_training + self.num_classes = num_classes + + with tf.variable_scope(scope): + # construct the model + net = conv2d(inputs, 64, 7, 2, scope="conv1") # -> [batch, 112, 112, 64] + net = tf.nn.relu(batch_norm(net, is_training=self.is_training, scope="bn1")) + net = max_pool(net, 3, 2, scope="maxpool1") # -> [batch, 56, 56, 64] + net = self._block(net, 256, 3, init_stride=1, is_training=self.is_training, + scope="block2") # -> [batch, 56, 56, 256] + net = self._block(net, 512, 4, is_training=self.is_training, scope="block3") + # -> [batch, 28, 28, 512] + net = self._block(net, 1024, 6, is_training=self.is_training, scope="block4") + # -> [batch, 14, 14, 1024] + net = self._block(net, 2048, 3, is_training=self.is_training, scope="block5") + # -> [batch, 7, 7, 2048] + net = avg_pool(net, 7, scope="avgpool5") # -> [batch, 1, 1, 2048] + net = tf.squeeze(net, [1, 2], name="SpatialSqueeze") # -> [batch, 2048] + self.logits = fc(net, self.num_classes, "fc6") # -> [batch, num_classes] + self.predictions = tf.nn.softmax(self.logits) + + + def _block(self, x, n_out, n, init_stride=2, is_training=True, scope="block"): + with tf.variable_scope(scope): + h_out = n_out // 4 + out = self._bottleneck(x, h_out, n_out, stride=init_stride, + is_training=is_training, scope="bottlencek1") + for i in range(1, n): + out = self._bottleneck(out, h_out, n_out, is_training=is_training, + scope=("bottlencek%s" % (i + 1))) + return out + + def _bottleneck(self, x, h_out, n_out, stride=None, is_training=True, scope="bottleneck"): + """ A residual bottleneck unit""" + n_in = x.get_shape()[-1] + if stride is None: + stride = 1 if n_in == n_out else 2 + + with tf.variable_scope(scope): + h = conv2d(x, h_out, 1, stride=stride, scope="conv_1") + h = batch_norm(h, is_training=is_training, scope="bn_1") + h = tf.nn.relu(h) + h = conv2d(h, h_out, 3, stride=1, scope="conv_2") + h = batch_norm(h, is_training=is_training, scope="bn_2") + h = tf.nn.relu(h) + h = conv2d(h, n_out, 1, stride=1, scope="conv_3") + h = batch_norm(h, is_training=is_training, scope="bn_3") + + if n_in != n_out: + shortcut = conv2d(x, n_out, 1, stride=stride, scope="conv_4") + shortcut = batch_norm(shortcut, is_training=is_training, scope="bn_4") + else: + shortcut = x + return tf.nn.relu(shortcut + h) + +if __name__ == "__main__": + x = tf.random_normal([32, 224, 224, 3]) + resnet50 = ResNet50(x) + print(resnet50.logits) \ No newline at end of file diff --git a/CNNs/ShuffleNet.py b/CNNs/ShuffleNet.py new file mode 100644 index 0000000..50c4fc8 --- /dev/null +++ b/CNNs/ShuffleNet.py @@ -0,0 +1,122 @@ +""" +implement a shuffleNet by pytorch +""" +import torch +import torch.nn as nn +import torch.nn.functional as F +from torch.autograd import Variable + +dtype = torch.FloatTensor + +def shuffle_channels(x, groups): + """shuffle channels of a 4-D Tensor""" + batch_size, channels, height, width = x.size() + assert channels % groups == 0 + channels_per_group = channels // groups + # split into groups + x = x.view(batch_size, groups, channels_per_group, + height, width) + # transpose 1, 2 axis + x = x.transpose(1, 2).contiguous() + # reshape into orignal + x = x.view(batch_size, channels, height, width) + return x + +class ShuffleNetUnitA(nn.Module): + """ShuffleNet unit for stride=1""" + def __init__(self, in_channels, out_channels, groups=3): + super(ShuffleNetUnitA, self).__init__() + assert in_channels == out_channels + assert out_channels % 4 == 0 + bottleneck_channels = out_channels // 4 + self.groups = groups + self.group_conv1 = nn.Conv2d(in_channels, bottleneck_channels, + 1, groups=groups, stride=1) + self.bn2 = nn.BatchNorm2d(bottleneck_channels) + self.depthwise_conv3 = nn.Conv2d(bottleneck_channels, + bottleneck_channels, + 3, padding=1, stride=1, + groups=bottleneck_channels) + self.bn4 = nn.BatchNorm2d(bottleneck_channels) + self.group_conv5 = nn.Conv2d(bottleneck_channels, out_channels, + 1, stride=1, groups=groups) + self.bn6 = nn.BatchNorm2d(out_channels) + + def forward(self, x): + out = self.group_conv1(x) + out = F.relu(self.bn2(out)) + out = shuffle_channels(out, groups=self.groups) + out = self.depthwise_conv3(out) + out = self.bn4(out) + out = self.group_conv5(out) + out = self.bn6(out) + out = F.relu(x + out) + return out + +class ShuffleNetUnitB(nn.Module): + """ShuffleNet unit for stride=2""" + def __init__(self, in_channels, out_channels, groups=3): + super(ShuffleNetUnitB, self).__init__() + out_channels -= in_channels + assert out_channels % 4 == 0 + bottleneck_channels = out_channels // 4 + self.groups = groups + self.group_conv1 = nn.Conv2d(in_channels, bottleneck_channels, + 1, groups=groups, stride=1) + self.bn2 = nn.BatchNorm2d(bottleneck_channels) + self.depthwise_conv3 = nn.Conv2d(bottleneck_channels, + bottleneck_channels, + 3, padding=1, stride=2, + groups=bottleneck_channels) + self.bn4 = nn.BatchNorm2d(bottleneck_channels) + self.group_conv5 = nn.Conv2d(bottleneck_channels, out_channels, + 1, stride=1, groups=groups) + self.bn6 = nn.BatchNorm2d(out_channels) + + def forward(self, x): + out = self.group_conv1(x) + out = F.relu(self.bn2(out)) + out = shuffle_channels(out, groups=self.groups) + out = self.depthwise_conv3(out) + out = self.bn4(out) + out = self.group_conv5(out) + out = self.bn6(out) + x = F.avg_pool2d(x, 3, stride=2, padding=1) + out = F.relu(torch.cat([x, out], dim=1)) + return out + +class ShuffleNet(nn.Module): + """ShuffleNet for groups=3""" + def __init__(self, groups=3, in_channels=3, num_classes=1000): + super(ShuffleNet, self).__init__() + + self.conv1 = nn.Conv2d(in_channels, 24, 3, stride=2, padding=1) + stage2_seq = [ShuffleNetUnitB(24, 240, groups=3)] + \ + [ShuffleNetUnitA(240, 240, groups=3) for i in range(3)] + self.stage2 = nn.Sequential(*stage2_seq) + stage3_seq = [ShuffleNetUnitB(240, 480, groups=3)] + \ + [ShuffleNetUnitA(480, 480, groups=3) for i in range(7)] + self.stage3 = nn.Sequential(*stage3_seq) + stage4_seq = [ShuffleNetUnitB(480, 960, groups=3)] + \ + [ShuffleNetUnitA(960, 960, groups=3) for i in range(3)] + self.stage4 = nn.Sequential(*stage4_seq) + self.fc = nn.Linear(960, num_classes) + + def forward(self, x): + net = self.conv1(x) + net = F.max_pool2d(net, 3, stride=2, padding=1) + net = self.stage2(net) + net = self.stage3(net) + net = self.stage4(net) + net = F.avg_pool2d(net, 7) + net = net.view(net.size(0), -1) + net = self.fc(net) + logits = F.softmax(net) + return logits + +if __name__ == "__main__": + x = Variable(torch.randn([32, 3, 224, 224]).type(dtype), + requires_grad=False) + shuffleNet = ShuffleNet() + out = shuffleNet(x) + print(out.size()) diff --git a/CNNs/SqueezeNet.py b/CNNs/SqueezeNet.py new file mode 100644 index 0000000..47a5b09 --- /dev/null +++ b/CNNs/SqueezeNet.py @@ -0,0 +1,74 @@ +""" +2017/12/02 +""" + +import tensorflow as tf +import numpy as np + + +class SqueezeNet(object): + def __init__(self, inputs, nb_classes=1000, is_training=True): + # conv1 + net = tf.layers.conv2d(inputs, 96, [7, 7], strides=[2, 2], + padding="SAME", activation=tf.nn.relu, + name="conv1") + # maxpool1 + net = tf.layers.max_pooling2d(net, [3, 3], strides=[2, 2], + name="maxpool1") + # fire2 + net = self._fire(net, 16, 64, "fire2") + # fire3 + net = self._fire(net, 16, 64, "fire3") + # fire4 + net = self._fire(net, 32, 128, "fire4") + # maxpool4 + net = tf.layers.max_pooling2d(net, [3, 3], strides=[2, 2], + name="maxpool4") + # fire5 + net = self._fire(net, 32, 128, "fire5") + # fire6 + net = self._fire(net, 48, 192, "fire6") + # fire7 + net = self._fire(net, 48, 192, "fire7") + # fire8 + net = self._fire(net, 64, 256, "fire8") + # maxpool8 + net = tf.layers.max_pooling2d(net, [3, 3], strides=[2, 2], + name="maxpool8") + # fire9 + net = self._fire(net, 64, 256, "fire9") + # dropout + net = tf.layers.dropout(net, 0.5, training=is_training) + # conv10 + net = tf.layers.conv2d(net, 1000, [1, 1], strides=[1, 1], + padding="SAME", activation=tf.nn.relu, + name="conv10") + # avgpool10 + net = tf.layers.average_pooling2d(net, [13, 13], strides=[1, 1], + name="avgpool10") + # squeeze the axis + net = tf.squeeze(net, axis=[1, 2]) + + self.logits = net + self.prediction = tf.nn.softmax(net) + + + def _fire(self, inputs, squeeze_depth, expand_depth, scope): + with tf.variable_scope(scope): + squeeze = tf.layers.conv2d(inputs, squeeze_depth, [1, 1], + strides=[1, 1], padding="SAME", + activation=tf.nn.relu, name="squeeze") + # squeeze + expand_1x1 = tf.layers.conv2d(squeeze, expand_depth, [1, 1], + strides=[1, 1], padding="SAME", + activation=tf.nn.relu, name="expand_1x1") + expand_3x3 = tf.layers.conv2d(squeeze, expand_depth, [3, 3], + strides=[1, 1], padding="SAME", + activation=tf.nn.relu, name="expand_3x3") + return tf.concat([expand_1x1, expand_3x3], axis=3) + + +if __name__ == "__main__": + inputs = tf.random_normal([32, 224, 224, 3]) + net = SqueezeNet(inputs) + print(net.prediction) diff --git a/CNNs/densenet.py b/CNNs/densenet.py new file mode 100644 index 0000000..8f70424 --- /dev/null +++ b/CNNs/densenet.py @@ -0,0 +1,228 @@ +""" +DenseNet, original: https://github.com/pytorch/vision/blob/master/torchvision/models/densenet.py +""" +import re +from collections import OrderedDict + +import torch +import torch.nn as nn +import torch.nn.functional as F +import torch.utils.model_zoo as model_zoo +import torchvision.transforms as transforms + +from PIL import Image +import numpy as np + +model_urls = { + 'densenet121': 'https://download.pytorch.org/models/densenet121-a639ec97.pth', + 'densenet169': 'https://download.pytorch.org/models/densenet169-b2777c0a.pth', + 'densenet201': 'https://download.pytorch.org/models/densenet201-c1103571.pth', + 'densenet161': 'https://download.pytorch.org/models/densenet161-8d451a50.pth', +} + + +class _DenseLayer(nn.Sequential): + """Basic unit of DenseBlock (using bottleneck layer) """ + def __init__(self, num_input_features, growth_rate, bn_size, drop_rate): + super(_DenseLayer, self).__init__() + self.add_module("norm1", nn.BatchNorm2d(num_input_features)) + self.add_module("relu1", nn.ReLU(inplace=True)) + self.add_module("conv1", nn.Conv2d(num_input_features, bn_size*growth_rate, + kernel_size=1, stride=1, bias=False)) + self.add_module("norm2", nn.BatchNorm2d(bn_size*growth_rate)) + self.add_module("relu2", nn.ReLU(inplace=True)) + self.add_module("conv2", nn.Conv2d(bn_size*growth_rate, growth_rate, + kernel_size=3, stride=1, padding=1, bias=False)) + self.drop_rate = drop_rate + + def forward(self, x): + new_features = super(_DenseLayer, self).forward(x) + if self.drop_rate > 0: + new_features = F.dropout(new_features, p=self.drop_rate, training=self.training) + return torch.cat([x, new_features], 1) + +class _DenseBlock(nn.Sequential): + """DenseBlock""" + def __init__(self, num_layers, num_input_features, bn_size, growth_rate, drop_rate): + super(_DenseBlock, self).__init__() + for i in range(num_layers): + layer = _DenseLayer(num_input_features+i*growth_rate, growth_rate, bn_size, + drop_rate) + self.add_module("denselayer%d" % (i+1,), layer) + + +class _Transition(nn.Sequential): + """Transition layer between two adjacent DenseBlock""" + def __init__(self, num_input_feature, num_output_features): + super(_Transition, self).__init__() + self.add_module("norm", nn.BatchNorm2d(num_input_feature)) + self.add_module("relu", nn.ReLU(inplace=True)) + self.add_module("conv", nn.Conv2d(num_input_feature, num_output_features, + kernel_size=1, stride=1, bias=False)) + self.add_module("pool", nn.AvgPool2d(2, stride=2)) + + +class DenseNet(nn.Module): + "DenseNet-BC model" + def __init__(self, growth_rate=32, block_config=(6, 12, 24, 16), num_init_features=64, + bn_size=4, compression_rate=0.5, drop_rate=0, num_classes=1000): + """ + :param growth_rate: (int) number of filters used in DenseLayer, `k` in the paper + :param block_config: (list of 4 ints) number of layers in each DenseBlock + :param num_init_features: (int) number of filters in the first Conv2d + :param bn_size: (int) the factor using in the bottleneck layer + :param compression_rate: (float) the compression rate used in Transition Layer + :param drop_rate: (float) the drop rate after each DenseLayer + :param num_classes: (int) number of classes for classification + """ + super(DenseNet, self).__init__() + # first Conv2d + self.features = nn.Sequential(OrderedDict([ + ("conv0", nn.Conv2d(3, num_init_features, kernel_size=7, stride=2, padding=3, bias=False)), + ("norm0", nn.BatchNorm2d(num_init_features)), + ("relu0", nn.ReLU(inplace=True)), + ("pool0", nn.MaxPool2d(3, stride=2, padding=1)) + ])) + + # DenseBlock + num_features = num_init_features + for i, num_layers in enumerate(block_config): + block = _DenseBlock(num_layers, num_features, bn_size, growth_rate, drop_rate) + self.features.add_module("denseblock%d" % (i + 1), block) + num_features += num_layers*growth_rate + if i != len(block_config) - 1: + transition = _Transition(num_features, int(num_features*compression_rate)) + self.features.add_module("transition%d" % (i + 1), transition) + num_features = int(num_features * compression_rate) + + # final bn+ReLU + self.features.add_module("norm5", nn.BatchNorm2d(num_features)) + self.features.add_module("relu5", nn.ReLU(inplace=True)) + + # classification layer + self.classifier = nn.Linear(num_features, num_classes) + + # params initialization + for m in self.modules(): + if isinstance(m, nn.Conv2d): + nn.init.kaiming_normal_(m.weight) + elif isinstance(m, nn.BatchNorm2d): + nn.init.constant_(m.bias, 0) + nn.init.constant_(m.weight, 1) + elif isinstance(m, nn.Linear): + nn.init.constant_(m.bias, 0) + + def forward(self, x): + features = self.features(x) + out = F.avg_pool2d(features, 7, stride=1).view(features.size(0), -1) + out = self.classifier(out) + return out + +class DenseNet_MNIST(nn.Module): + """DenseNet for MNIST dataset""" + def __init__(self, growth_rate=12, block_config=(6, 6, 6), num_init_features=16, + bn_size=4, compression_rate=0.5, drop_rate=0, num_classes=10): + """ + :param growth_rate: (int) number of filters used in DenseLayer, `k` in the paper + :param block_config: (list of 2 ints) number of layers in each DenseBlock + :param num_init_features: (int) number of filters in the first Conv2d + :param bn_size: (int) the factor using in the bottleneck layer + :param compression_rate: (float) the compression rate used in Transition Layer + :param drop_rate: (float) the drop rate after each DenseLayer + :param num_classes: (int) number of classes for classification + """ + super(DenseNet_MNIST, self).__init__() + # first Conv2d + self.features = nn.Sequential(OrderedDict([ + ("conv0", nn.Conv2d(1, num_init_features, kernel_size=3, stride=1, padding=1, bias=False)), + ("norm0", nn.BatchNorm2d(num_init_features)), + ("relu0", nn.ReLU(inplace=True)), + ])) + + # DenseBlock + num_features = num_init_features + for i, num_layers in enumerate(block_config): + block = _DenseBlock(num_layers, num_features, bn_size, growth_rate, drop_rate) + self.features.add_module("denseblock%d" % (i + 1), block) + num_features += num_layers * growth_rate + if i != len(block_config) - 1: + transition = _Transition(num_features, int(num_features * compression_rate)) + self.features.add_module("transition%d" % (i + 1), transition) + num_features = int(num_features * compression_rate) + + # final bn+ReLU + self.features.add_module("norm5", nn.BatchNorm2d(num_features)) + self.features.add_module("relu5", nn.ReLU(inplace=True)) + + # classification layer + self.classifier = nn.Linear(num_features, num_classes) + + # params initialization + for m in self.modules(): + if isinstance(m, nn.Conv2d): + nn.init.kaiming_normal_(m.weight) + elif isinstance(m, nn.BatchNorm2d): + nn.init.constant_(m.bias, 0) + nn.init.constant_(m.weight, 1) + elif isinstance(m, nn.Linear): + nn.init.constant_(m.bias, 0) + + def forward(self, x): + features = self.features(x) + out = F.avg_pool2d(features, 7, stride=1).view(features.size(0), -1) + out = self.classifier(out) + return out + + +def densenet121(pretrained=False, **kwargs): + """DenseNet121""" + model = DenseNet(num_init_features=64, growth_rate=32, block_config=(6, 12, 24, 16), + **kwargs) + + if pretrained: + # '.'s are no longer allowed in module names, but pervious _DenseLayer + # has keys 'norm.1', 'relu.1', 'conv.1', 'norm.2', 'relu.2', 'conv.2'. + # They are also in the checkpoints in model_urls. This pattern is used + # to find such keys. + pattern = re.compile( + r'^(.*denselayer\d+\.(?:norm|relu|conv))\.((?:[12])\.(?:weight|bias|running_mean|running_var))$') + state_dict = model_zoo.load_url(http://github.com/model_urls['densenet121']) + for key in list(state_dict.keys()): + res = pattern.match(key) + if res: + new_key = res.group(1) + res.group(2) + state_dict[new_key] = state_dict[key] + del state_dict[key] + model.load_state_dict(state_dict) + return model + +if __name__ == "__main__": + densenet = densenet121(pretrained=True) + densenet.eval() + + img = Image.open("./images/cat.jpg") + + trans_ops = transforms.Compose([ + transforms.Resize(256), + transforms.CenterCrop(224), + transforms.ToTensor(), + transforms.Normalize(mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]) + ]) + + images = trans_ops(img).view(-1, 3, 224, 224) + print(images) + outputs = densenet(images) + + _, predictions = outputs.topk(5, dim=1) + + labels = list(map(lambda s: s.strip(), open("./data/imagenet/synset_words.txt").readlines())) + for idx in predictions.numpy()[0]: + print("Predicted labels:", labels[idx]) + + + + + + + diff --git a/CNNs/mobilenet_v2.py b/CNNs/mobilenet_v2.py new file mode 100644 index 0000000..23d6c0f --- /dev/null +++ b/CNNs/mobilenet_v2.py @@ -0,0 +1,349 @@ +""" +2018-11-24 +""" + +from collections import namedtuple +import copy + +import tensorflow as tf + +slim = tf.contrib.slim + +def _make_divisible(v, divisor, min_value=None): + """make `v` is divided exactly by `divisor`, but keep the min_value""" + if min_value is None: + min_value = divisor + new_v = max(min_value, int(v + divisor / 2) // divisor * divisor) + # Make sure that round down does not go down by more than 10%. + if new_v < 0.9 * v: + new_v += divisor + return new_v + + +@slim.add_arg_scope +def _depth_multiplier_func(params, + multiplier, + divisible_by=8, + min_depth=8): + """get the new channles""" + if 'num_outputs' not in params: + return + d = params['num_outputs'] + params['num_outputs'] = _make_divisible(d * multiplier, divisible_by, + min_depth) + +def _fixed_padding(inputs, kernel_size, rate=1): + """Pads the input along the spatial dimensions independently of input size. + Pads the input such that if it was used in a convolution with 'VALID' padding, + the output would have the same dimensions as if the unpadded input was used + in a convolution with 'SAME' padding. + Args: + inputs: A tensor of size [batch, height_in, width_in, channels]. + kernel_size: The kernel to be used in the conv2d or max_pool2d operation. + rate: An integer, rate for atrous convolution. + Returns: + output: A tensor of size [batch, height_out, width_out, channels] with the + input, either intact (if kernel_size == 1) or padded (if kernel_size > 1). + """ + kernel_size_effective = [kernel_size[0] + (kernel_size[0] - 1) * (rate - 1), + kernel_size[0] + (kernel_size[0] - 1) * (rate - 1)] + pad_total = [kernel_size_effective[0] - 1, kernel_size_effective[1] - 1] + pad_beg = [pad_total[0] // 2, pad_total[1] // 2] + pad_end = [pad_total[0] - pad_beg[0], pad_total[1] - pad_beg[1]] + padded_inputs = tf.pad(inputs, [[0, 0], [pad_beg[0], pad_end[0]], + [pad_beg[1], pad_end[1]], [0, 0]]) + return padded_inputs + + +@slim.add_arg_scope +def expanded_conv(x, + num_outputs, + expansion=6, + stride=1, + rate=1, + normalizer_fn=slim.batch_norm, + project_activation_fn=tf.identity, + padding="SAME", + scope=None): + """The expand conv op in MobileNetv2 + 1x1 conv -> depthwise 3x3 conv -> 1x1 linear conv + """ + with tf.variable_scope(scope, default_name="expanded_conv") as s, \ + tf.name_scope(s.original_name_scope): + prev_depth = x.get_shape().as_list()[3] + # the filters of expanded conv + inner_size = prev_depth * expansion + net = x + # only inner_size > prev_depth, use expanded conv + if inner_size > prev_depth: + net = slim.conv2d(net, inner_size, 1, normalizer_fn=normalizer_fn, + scope="expand") + # depthwise conv + net = slim.separable_conv2d(net, num_outputs=None, kernel_size=3, + depth_multiplier=1, stride=stride, + rate=rate, normalizer_fn=normalizer_fn, + padding=padding, scope="depthwise") + # projection + net = slim.conv2d(net, num_outputs, 1, normalizer_fn=normalizer_fn, + activation_fn=project_activation_fn, scope="project") + + # residual connection + if stride == 1 and net.get_shape().as_list()[-1] == prev_depth: + net += x + + return net + +def global_pool(x, pool_op=tf.nn.avg_pool): + """Applies avg pool to produce 1x1 output. + NOTE: This function is funcitonally equivalenet to reduce_mean, but it has + baked in average pool which has better support across hardware. + Args: + input_tensor: input tensor + pool_op: pooling op (avg pool is default) + Returns: + a tensor batch_size x 1 x 1 x depth. + """ + shape = x.get_shape().as_list() + if shape[1] is None or shape[2] is None: + kernel_size = tf.convert_to_tensor( + [1, tf.shape(x)[1], tf.shape(x)[2], 1]) + else: + kernel_size = [1, shape[1], shape[2], 1] + output = pool_op(x, ksize=kernel_size, strides=[1, 1, 1, 1], padding='VALID') + # Recover output shape, for unknown shape. + output.set_shape([None, 1, 1, None]) + return output + + +_Op = namedtuple("Op", ['op', 'params', 'multiplier_func']) + +def op(op_func, **params): + return _Op(op=op_func, params=params, + multiplier_func=_depth_multiplier_func) + + +CONV_DEF = [op(slim.conv2d, num_outputs=32, stride=2, kernel_size=3), + op(expanded_conv, num_outputs=16, expansion=1), + op(expanded_conv, num_outputs=24, stride=2), + op(expanded_conv, num_outputs=24, stride=1), + op(expanded_conv, num_outputs=32, stride=2), + op(expanded_conv, num_outputs=32, stride=1), + op(expanded_conv, num_outputs=32, stride=1), + op(expanded_conv, num_outputs=64, stride=2), + op(expanded_conv, num_outputs=64, stride=1), + op(expanded_conv, num_outputs=64, stride=1), + op(expanded_conv, num_outputs=64, stride=1), + op(expanded_conv, num_outputs=96, stride=1), + op(expanded_conv, num_outputs=96, stride=1), + op(expanded_conv, num_outputs=96, stride=1), + op(expanded_conv, num_outputs=160, stride=2), + op(expanded_conv, num_outputs=160, stride=1), + op(expanded_conv, num_outputs=160, stride=1), + op(expanded_conv, num_outputs=320, stride=1), + op(slim.conv2d, num_outputs=1280, stride=1, kernel_size=1), + ] + + +def mobilenet_arg_scope(is_training=True, + weight_decay=0.00004, + stddev=0.09, + dropout_keep_prob=0.8, + bn_decay=0.997): + """Defines Mobilenet default arg scope. + Usage: + with tf.contrib.slim.arg_scope(mobilenet.training_scope()): + logits, endpoints = mobilenet_v2.mobilenet(input_tensor) + # the network created will be trainble with dropout/batch norm + # initialized appropriately. + Args: + is_training: if set to False this will ensure that all customizations are + set to non-training mode. This might be helpful for code that is reused + across both training/evaluation, but most of the time training_scope with + value False is not needed. If this is set to None, the parameters is not + added to the batch_norm arg_scope. + weight_decay: The weight decay to use for regularizing the model. + stddev: Standard deviation for initialization, if negative uses xavier. + dropout_keep_prob: dropout keep probability (not set if equals to None). + bn_decay: decay for the batch norm moving averages (not set if equals to + None). + Returns: + An argument scope to use via arg_scope. + """ + # Note: do not introduce parameters that would change the inference + # model here (for example whether to use bias), modify conv_def instead. + batch_norm_params = { + 'center': True, + 'scale': True, + 'decay': bn_decay, + 'is_training': is_training + } + if stddev < 0: + weight_intitializer = slim.initializers.xavier_initializer() + else: + weight_intitializer = tf.truncated_normal_initializer(stddev=stddev) + + # Set weight_decay for weights in Conv and FC layers. + with slim.arg_scope( + [slim.conv2d, slim.fully_connected, slim.separable_conv2d], + weights_initializer=weight_intitializer, + normalizer_fn=slim.batch_norm, + activation_fn=tf.nn.relu6), \ + slim.arg_scope([slim.batch_norm], **batch_norm_params), \ + slim.arg_scope([slim.dropout], is_training=is_training, + keep_prob=dropout_keep_prob), \ + slim.arg_scope([slim.conv2d, slim.separable_conv2d], + biases_initializer=None, + padding="SAME"), \ + slim.arg_scope([slim.conv2d], + weights_regularizer=slim.l2_regularizer(weight_decay)), \ + slim.arg_scope([slim.separable_conv2d], weights_regularizer=None) as s: + return s + + +def mobilenetv2(x, + num_classes=1001, + depth_multiplier=1.0, + scope='MobilenetV2', + finegrain_classification_mode=False, + min_depth=8, + divisible_by=8, + output_stride=None, + ): + """Mobilenet v2 + Args: + x: The input tensor + num_classes: number of classes + depth_multiplier: The multiplier applied to scale number of + channels in each layer. Note: this is called depth multiplier in the + paper but the name is kept for consistency with slim's model builder. + scope: Scope of the operator + finegrain_classification_mode: When set to True, the model + will keep the last layer large even for small multipliers. + The paper suggests that it improves performance for ImageNet-type of problems. + min_depth: If provided, will ensure that all layers will have that + many channels after application of depth multiplier. + divisible_by: If provided will ensure that all layers # channels + will be divisible by this number. + """ + conv_defs = CONV_DEF + + # keep the last conv layer very larger channel + if finegrain_classification_mode: + conv_defs = copy.deepcopy(conv_defs) + if depth_multiplier < 1: + conv_defs[-1].params['num_outputs'] /= depth_multiplier + + depth_args = {} + # NB: do not set depth_args unless they are provided to avoid overriding + # whatever default depth_multiplier might have thanks to arg_scope. + if min_depth is not None: + depth_args['min_depth'] = min_depth + if divisible_by is not None: + depth_args['divisible_by'] = divisible_by + + with slim.arg_scope([_depth_multiplier_func], **depth_args): + with tf.variable_scope(scope, default_name='Mobilenet'): + # The current_stride variable keeps track of the output stride of the + # activations, i.e., the running product of convolution strides up to the + # current network layer. This allows us to invoke atrous convolution + # whenever applying the next convolution would result in the activations + # having output stride larger than the target output_stride. + current_stride = 1 + + # The atrous convolution rate parameter. + rate = 1 + + net = x + # Insert default parameters before the base scope which includes + # any custom overrides set in mobilenet. + end_points = {} + scopes = {} + for i, opdef in enumerate(conv_defs): + params = dict(opdef.params) + opdef.multiplier_func(params, depth_multiplier) + stride = params.get('stride', 1) + if output_stride is not None and current_stride == output_stride: + # If we have reached the target output_stride, then we need to employ + # atrous convolution with stride=1 and multiply the atrous rate by the + # current unit's stride for use in subsequent layers. + layer_stride = 1 + layer_rate = rate + rate *= stride + else: + layer_stride = stride + layer_rate = 1 + current_stride *= stride + # Update params. + params['stride'] = layer_stride + # Only insert rate to params if rate > 1. + if layer_rate > 1: + params['rate'] = layer_rate + + try: + net = opdef.op(net, **params) + except Exception: + raise ValueError('Failed to create op %i: %r params: %r' % (i, opdef, params)) + + with tf.variable_scope('Logits'): + net = global_pool(net) + end_points['global_pool'] = net + if not num_classes: + return net, end_points + net = slim.dropout(net, scope='Dropout') + # 1 x 1 x num_classes + # Note: legacy scope name. + logits = slim.conv2d( + net, + num_classes, [1, 1], + activation_fn=None, + normalizer_fn=None, + biases_initializer=tf.zeros_initializer(), + scope='Conv2d_1c_1x1') + + logits = tf.squeeze(logits, [1, 2]) + + return logits + + +if __name__ == "__main__": + import cv2 + import numpy as np + + inputs = tf.placeholder(tf.uint8, [None, None, 3]) + images = tf.expand_dims(inputs, 0) + images = tf.cast(images, tf.float32) / 128. - 1 + images.set_shape((None, None, None, 3)) + images = tf.image.resize_images(images, (224, 224)) + + with slim.arg_scope(mobilenet_arg_scope(is_training=False)): + logits = mobilenetv2(images) + + # Restore using exponential moving average since it produces (1.5-2%) higher + # accuracy + ema = tf.train.ExponentialMovingAverage(0.999) + vars = ema.variables_to_restore() + + saver = tf.train.Saver(vars) + + print(len(tf.global_variables())) + for var in tf.global_variables(): + print(var) + checkpoint_path = r"C:\Users\xiaoh\Desktop\temp\mobilenet_v2_1.0_224\mobilenet_v2_1.0_224.ckpt" + image_file = "C:/Users/xiaoh/Desktop/temp/pandas.jpg" + with tf.Session() as sess: + saver.restore(sess, checkpoint_path) + + img = cv2.imread(image_file) + img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) + + print(np.argmax(sess.run(logits, feed_dict={inputs: img})[0])) + + + + + + + + + + diff --git a/CNNs/shufflenet_v2.py b/CNNs/shufflenet_v2.py new file mode 100644 index 0000000..dbb25c9 --- /dev/null +++ b/CNNs/shufflenet_v2.py @@ -0,0 +1,243 @@ +""" +The implement of shufflenet_v2 by Keras +""" + +import tensorflow as tf +from tensorflow.keras.layers import Conv2D, DepthwiseConv2D +from tensorflow.keras.layers import MaxPool2D, GlobalAveragePooling2D, Dense +from tensorflow.keras.layers import BatchNormalization, Activation + + +def channle_shuffle(inputs, group): + """Shuffle the channel + Args: + inputs: 4D Tensor + group: int, number of groups + Returns: + Shuffled 4D Tensor + """ + in_shape = inputs.get_shape().as_list() + h, w, in_channel = in_shape[1:] + assert in_channel % group == 0 + l = tf.reshape(inputs, [-1, h, w, in_channel // group, group]) + l = tf.transpose(l, [0, 1, 2, 4, 3]) + l = tf.reshape(l, [-1, h, w, in_channel]) + + return l + +class Conv2D_BN_ReLU(tf.keras.Model): + """Conv2D -> BN -> ReLU""" + def __init__(self, channel, kernel_size=1, stride=1): + super(Conv2D_BN_ReLU, self).__init__() + + self.conv = Conv2D(channel, kernel_size, strides=stride, + padding="SAME", use_bias=False) + self.bn = BatchNormalization(axis=-1, momentum=0.9, epsilon=1e-5) + self.relu = Activation("relu") + + def call(self, inputs, training=True): + x = self.conv(inputs) + x = self.bn(x, training=training) + x = self.relu(x) + return x + +class DepthwiseConv2D_BN(tf.keras.Model): + """DepthwiseConv2D -> BN""" + def __init__(self, kernel_size=3, stride=1): + super(DepthwiseConv2D_BN, self).__init__() + + self.dconv = DepthwiseConv2D(kernel_size, strides=stride, + depth_multiplier=1, + padding="SAME", use_bias=False) + self.bn = BatchNormalization(axis=-1, momentum=0.9, epsilon=1e-5) + + def call(self, inputs, training=True): + x = self.dconv(inputs) + x = self.bn(x, training=training) + return x + + +class ShufflenetUnit1(tf.keras.Model): + def __init__(self, out_channel): + """The unit of shufflenetv2 for stride=1 + Args: + out_channel: int, number of channels + """ + super(ShufflenetUnit1, self).__init__() + + assert out_channel % 2 == 0 + self.out_channel = out_channel + + self.conv1_bn_relu = Conv2D_BN_ReLU(out_channel // 2, 1, 1) + self.dconv_bn = DepthwiseConv2D_BN(3, 1) + self.conv2_bn_relu = Conv2D_BN_ReLU(out_channel // 2, 1, 1) + + def call(self, inputs, training=False): + # split the channel + shortcut, x = tf.split(inputs, 2, axis=3) + + x = self.conv1_bn_relu(x, training=training) + x = self.dconv_bn(x, training=training) + x = self.conv2_bn_relu(x, training=training) + + x = tf.concat([shortcut, x], axis=3) + x = channle_shuffle(x, 2) + return x + +class ShufflenetUnit2(tf.keras.Model): + """The unit of shufflenetv2 for stride=2""" + def __init__(self, in_channel, out_channel): + super(ShufflenetUnit2, self).__init__() + + assert out_channel % 2 == 0 + self.in_channel = in_channel + self.out_channel = out_channel + + self.conv1_bn_relu = Conv2D_BN_ReLU(out_channel // 2, 1, 1) + self.dconv_bn = DepthwiseConv2D_BN(3, 2) + self.conv2_bn_relu = Conv2D_BN_ReLU(out_channel - in_channel, 1, 1) + + # for shortcut + self.shortcut_dconv_bn = DepthwiseConv2D_BN(3, 2) + self.shortcut_conv_bn_relu = Conv2D_BN_ReLU(in_channel, 1, 1) + + def call(self, inputs, training=False): + shortcut, x = inputs, inputs + + x = self.conv1_bn_relu(x, training=training) + x = self.dconv_bn(x, training=training) + x = self.conv2_bn_relu(x, training=training) + + shortcut = self.shortcut_dconv_bn(shortcut, training=training) + shortcut = self.shortcut_conv_bn_relu(shortcut, training=training) + + x = tf.concat([shortcut, x], axis=3) + x = channle_shuffle(x, 2) + return x + +class ShufflenetStage(tf.keras.Model): + """The stage of shufflenet""" + def __init__(self, in_channel, out_channel, num_blocks): + super(ShufflenetStage, self).__init__() + + self.in_channel = in_channel + self.out_channel = out_channel + + self.ops = [] + for i in range(num_blocks): + if i == 0: + op = ShufflenetUnit2(in_channel, out_channel) + else: + op = ShufflenetUnit1(out_channel) + self.ops.append(op) + + def call(self, inputs, training=False): + x = inputs + for op in self.ops: + x = op(x, training=training) + return x + + +class ShuffleNetv2(tf.keras.Model): + """Shufflenetv2""" + def __init__(self, num_classes, first_channel=24, channels_per_stage=(116, 232, 464)): + super(ShuffleNetv2, self).__init__() + + self.num_classes = num_classes + + self.conv1_bn_relu = Conv2D_BN_ReLU(first_channel, 3, 2) + self.pool1 = MaxPool2D(3, strides=2, padding="SAME") + self.stage2 = ShufflenetStage(first_channel, channels_per_stage[0], 4) + self.stage3 = ShufflenetStage(channels_per_stage[0], channels_per_stage[1], 8) + self.stage4 = ShufflenetStage(channels_per_stage[1], channels_per_stage[2], 4) + self.conv5_bn_relu = Conv2D_BN_ReLU(1024, 1, 1) + self.gap = GlobalAveragePooling2D() + self.linear = Dense(num_classes) + + def call(self, inputs, training=False): + x = self.conv1_bn_relu(inputs, training=training) + x = self.pool1(x) + x = self.stage2(x, training=training) + x = self.stage3(x, training=training) + x = self.stage4(x, training=training) + x = self.conv5_bn_relu(x, training=training) + x = self.gap(x) + x = self.linear(x) + return x + + +if __name__ =="__main__": + """ + inputs = tf.placeholder(tf.float32, [None, 224, 224, 3]) + + model = ShuffleNetv2(1000) + outputs = model(inputs) + + print(model.summary()) + + with tf.Session() as sess: + pass + + + vars = [] + for v in tf.global_variables(): + + vars.append((v.name, v)) + print(v.name) + print(len(vars)) + + + import numpy as np + + path = "C:/models/ShuffleNetV2-1x.npz" + weights = np.load(path) + np_vars = [] + for k in weights: + k_ = k.replace("beta", "gbeta") + k_ = k_.replace("/dconv", "/conv10_dconv") + k_ = k_.replace("shortcut_dconv", "shortcut_a_dconv") + k_ = k_.replace("conv5", "su_conv5") + k_ = k_.replace("linear", "t_linear") + np_vars.append((k_, weights[k])) + np_vars.sort(key=lambda x: x[0]) + + for k, _ in np_vars: + print(k) + + saver = tf.train.Saver(tf.global_variables()) + with tf.Session() as sess: + sess.run(tf.global_variables_initializer()) + + assign_ops = [] + for id in range(len(vars)): + print(vars[id][0], np_vars[id][0]) + assign_ops.append(tf.assign(vars[id][1], np_vars[id][1])) + + sess.run(assign_ops) + saver.save(sess, "./models/shufflene_v2_1.0.ckpt") + + model.save("./models/shufflenet_v2_1.0.hdf5") + + """ + + import numpy as np + from tensorflow.keras.preprocessing import image + from tensorflow.keras.applications.densenet import preprocess_input, decode_predictions + + img_path = './images/cat.jpg' + img = image.load_img(img_path, target_size=(224, 224)) + x = image.img_to_array(img) + x = np.expand_dims(x, axis=0) + x = preprocess_input(x) + + inputs = tf.placeholder(tf.float32, [None, 224, 224, 3]) + model = ShuffleNetv2(1000) + outputs = model(inputs, training=False) + outputs = tf.nn.softmax(outputs) + + saver = tf.train.Saver() + with tf.Session() as sess: + saver.restore(sess, "./models/shufflene_v2_1.0.ckpt") + preds = sess.run(outputs, feed_dict={inputs: x}) + print(decode_predictions(preds, top=3)[0]) + diff --git a/ObjectDetections/SSD/SSD_demo.py b/ObjectDetections/SSD/SSD_demo.py new file mode 100644 index 0000000..bfc42a4 --- /dev/null +++ b/ObjectDetections/SSD/SSD_demo.py @@ -0,0 +1,33 @@ +""" +SSD demo +""" + +import cv2 +import numpy as np +import tensorflow as tf +import matplotlib.image as mpimg + +from ssd_300_vgg import SSD +from utils import preprocess_image, process_bboxes +from visualization import plt_bboxes + + +ssd_net = SSD() +classes, scores, bboxes = ssd_net.detections() +images = ssd_net.images() + +sess = tf.Session() +# Restore SSD model. +ckpt_filename = './ssd_checkpoints/ssd_vgg_300_weights.ckpt' +sess.run(tf.global_variables_initializer()) +saver = tf.train.Saver() +saver.restore(sess, ckpt_filename) + +img = cv2.imread('./demo/dog.jpg') +img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) +img_prepocessed = preprocess_image(img) +rclasses, rscores, rbboxes = sess.run([classes, scores, bboxes], + feed_dict={images: img_prepocessed}) +rclasses, rscores, rbboxes = process_bboxes(rclasses, rscores, rbboxes) + +plt_bboxes(img, rclasses, rscores, rbboxes) diff --git a/ObjectDetections/SSD/demo/README.md b/ObjectDetections/SSD/demo/README.md new file mode 100644 index 0000000..c200906 --- /dev/null +++ b/ObjectDetections/SSD/demo/README.md @@ -0,0 +1 @@ +222 diff --git a/ObjectDetections/SSD/demo/car2.jpg b/ObjectDetections/SSD/demo/car2.jpg new file mode 100644 index 0000000..8c24a69 Binary files /dev/null and b/ObjectDetections/SSD/demo/car2.jpg differ diff --git a/ObjectDetections/SSD/demo/dog.jpg b/ObjectDetections/SSD/demo/dog.jpg new file mode 100644 index 0000000..665a81c Binary files /dev/null and b/ObjectDetections/SSD/demo/dog.jpg differ diff --git a/ObjectDetections/SSD/demo/eagle.jpg b/ObjectDetections/SSD/demo/eagle.jpg new file mode 100644 index 0000000..8b75095 Binary files /dev/null and b/ObjectDetections/SSD/demo/eagle.jpg differ diff --git a/ObjectDetections/SSD/demo/horses.jpg b/ObjectDetections/SSD/demo/horses.jpg new file mode 100644 index 0000000..3a761f4 Binary files /dev/null and b/ObjectDetections/SSD/demo/horses.jpg differ diff --git a/ObjectDetections/SSD/demo/person.jpg b/ObjectDetections/SSD/demo/person.jpg new file mode 100644 index 0000000..61d377f Binary files /dev/null and b/ObjectDetections/SSD/demo/person.jpg differ diff --git a/ObjectDetections/SSD/demo/street.jpg b/ObjectDetections/SSD/demo/street.jpg new file mode 100644 index 0000000..6750d37 Binary files /dev/null and b/ObjectDetections/SSD/demo/street.jpg differ diff --git a/ObjectDetections/SSD/ssd_300_vgg.py b/ObjectDetections/SSD/ssd_300_vgg.py new file mode 100644 index 0000000..42bef4d --- /dev/null +++ b/ObjectDetections/SSD/ssd_300_vgg.py @@ -0,0 +1,233 @@ +""" +SSD net (vgg_based) 300x300 +""" +from collections import namedtuple + +import numpy as np +import tensorflow as tf + +from ssd_layers import conv2d, max_pool2d, l2norm, dropout, \ + pad2d, ssd_multibox_layer +from ssd_anchors import ssd_anchors_all_layers + +# SSD parameters +SSDParams = namedtuple('SSDParameters', ['img_shape', # the input image size: 300x300 + 'num_classes', # number of classes: 20+1 + 'no_annotation_label', + 'feat_layers', # list of names of layer for detection + 'feat_shapes', # list of feature map sizes of layer for detection + 'anchor_size_bounds', # the down and upper bounds of anchor sizes + 'anchor_sizes', # list of anchor sizes of layer for detection + 'anchor_ratios', # list of rations used in layer for detection + 'anchor_steps', # list of cell size (pixel size) of layer for detection + 'anchor_offset', # the center point offset + 'normalizations', # list of normalizations of layer for detection + 'prior_scaling' # + ]) +class SSD(object): + """SSD net 300""" + def __init__(self, is_training=True): + self.is_training = is_training + self.threshold = 0.5 # class score threshold + self.ssd_params = SSDParams(img_shape=(300, 300), + num_classes=21, + no_annotation_label=21, + feat_layers=["block4", "block7", "block8", "block9", "block10", "block11"], + feat_shapes=[(38, 38), (19, 19), (10, 10), (5, 5), (3, 3), (1, 1)], + anchor_size_bounds=[0.15, 0.90], # diff from the original paper + anchor_sizes=[(21., 45.), + (45., 99.), + (99., 153.), + (153., 207.), + (207., 261.), + (261., 315.)], + anchor_ratios=[[2, .5], + [2, .5, 3, 1. / 3], + [2, .5, 3, 1. / 3], + [2, .5, 3, 1. / 3], + [2, .5], + [2, .5]], + anchor_steps=[8, 16, 32, 64, 100, 300], + anchor_offset=0.5, + normalizations=[20, -1, -1, -1, -1, -1], + prior_scaling=[0.1, 0.1, 0.2, 0.2] + ) + + predictions, logits, locations = self._built_net() + #self._update_feat_shapes_from_net() + classes, scores, bboxes = self._bboxes_select(predictions, locations) + self._classes = classes + self._scores = scores + self._bboxes = bboxes + + def _built_net(self): + """Construct the SSD net""" + self.end_points = {} # record the detection layers output + self._images = tf.placeholder(tf.float32, shape=[None, self.ssd_params.img_shape[0], + self.ssd_params.img_shape[1], 3]) + with tf.variable_scope("ssd_300_vgg"): + # original vgg layers + # block 1 + net = conv2d(self._images, 64, 3, scope="conv1_1") + net = conv2d(net, 64, 3, scope="conv1_2") + self.end_points["block1"] = net + net = max_pool2d(net, 2, scope="pool1") + # block 2 + net = conv2d(net, 128, 3, scope="conv2_1") + net = conv2d(net, 128, 3, scope="conv2_2") + self.end_points["block2"] = net + net = max_pool2d(net, 2, scope="pool2") + # block 3 + net = conv2d(net, 256, 3, scope="conv3_1") + net = conv2d(net, 256, 3, scope="conv3_2") + net = conv2d(net, 256, 3, scope="conv3_3") + self.end_points["block3"] = net + net = max_pool2d(net, 2, scope="pool3") + # block 4 + net = conv2d(net, 512, 3, scope="conv4_1") + net = conv2d(net, 512, 3, scope="conv4_2") + net = conv2d(net, 512, 3, scope="conv4_3") + self.end_points["block4"] = net + net = max_pool2d(net, 2, scope="pool4") + # block 5 + net = conv2d(net, 512, 3, scope="conv5_1") + net = conv2d(net, 512, 3, scope="conv5_2") + net = conv2d(net, 512, 3, scope="conv5_3") + self.end_points["block5"] = net + print(net) + net = max_pool2d(net, 3, stride=1, scope="pool5") + print(net) + + # additional SSD layers + # block 6: use dilate conv + net = conv2d(net, 1024, 3, dilation_rate=6, scope="conv6") + self.end_points["block6"] = net + #net = dropout(net, is_training=self.is_training) + # block 7 + net = conv2d(net, 1024, 1, scope="conv7") + self.end_points["block7"] = net + # block 8 + net = conv2d(net, 256, 1, scope="conv8_1x1") + net = conv2d(pad2d(net, 1), 512, 3, stride=2, scope="conv8_3x3", + padding="valid") + self.end_points["block8"] = net + # block 9 + net = conv2d(net, 128, 1, scope="conv9_1x1") + net = conv2d(pad2d(net, 1), 256, 3, stride=2, scope="conv9_3x3", + padding="valid") + self.end_points["block9"] = net + # block 10 + net = conv2d(net, 128, 1, scope="conv10_1x1") + net = conv2d(net, 256, 3, scope="conv10_3x3", padding="valid") + self.end_points["block10"] = net + # block 11 + net = conv2d(net, 128, 1, scope="conv11_1x1") + net = conv2d(net, 256, 3, scope="conv11_3x3", padding="valid") + self.end_points["block11"] = net + + # class and location predictions + predictions = [] + logits = [] + locations = [] + for i, layer in enumerate(self.ssd_params.feat_layers): + cls, loc = ssd_multibox_layer(self.end_points[layer], self.ssd_params.num_classes, + self.ssd_params.anchor_sizes[i], + self.ssd_params.anchor_ratios[i], + self.ssd_params.normalizations[i], scope=layer+"_box") + predictions.append(tf.nn.softmax(cls)) + logits.append(cls) + locations.append(loc) + return predictions, logits, locations + + def _update_feat_shapes_from_net(self, predictions): + """ Obtain the feature shapes from the prediction layers""" + new_feat_shapes = [] + for l in predictions: + new_feat_shapes.append(l.get_shape().as_list()[1:]) + self.ssd_params._replace(feat_shapes=new_feat_shapes) + + def anchors(self): + """Get sSD anchors""" + return ssd_anchors_all_layers(self.ssd_params.img_shape, + self.ssd_params.feat_shapes, + self.ssd_params.anchor_sizes, + self.ssd_params.anchor_ratios, + self.ssd_params.anchor_steps, + self.ssd_params.anchor_offset, + np.float32) + + def _bboxes_decode_layer(self, feat_locations, anchor_bboxes, prior_scaling): + """ + Decode the feat location of one layer + params: + feat_locations: 5D Tensor, [batch_size, size, size, n_anchors, 4] + anchor_bboxes: list of Tensors(y, x, w, h) + shape: [size,size,1], [size, size,1], [n_anchors], [n_anchors] + prior_scaling: list of 4 floats + """ + yref, xref, href, wref = anchor_bboxes + print(yref) + # Compute center, height and width + cx = feat_locations[:, :, :, :, 0] * wref * prior_scaling[0] + xref + cy = feat_locations[:, :, :, :, 1] * href * prior_scaling[1] + yref + w = wref * tf.exp(feat_locations[:, :, :, :, 2] * prior_scaling[2]) + h = href * tf.exp(feat_locations[:, :, :, :, 3] * prior_scaling[3]) + # compute boxes coordinates (ymin, xmin, ymax,,xmax) + bboxes = tf.stack([cy - h / 2., cx - w / 2., + cy + h / 2., cx + w / 2.], axis=-1) + # shape [batch_size, size, size, n_anchors, 4] + return bboxes + + def _bboxes_select_layer(self, feat_predictions, feat_locations, anchor_bboxes, + prior_scaling): + """Select boxes from the feat layer, only for bacth_size=1""" + n_bboxes = np.product(feat_predictions.get_shape().as_list()[1:-1]) + # decode the location + bboxes = self._bboxes_decode_layer(feat_locations, anchor_bboxes, prior_scaling) + bboxes = tf.reshape(bboxes, [n_bboxes, 4]) + predictions = tf.reshape(feat_predictions, [n_bboxes, self.ssd_params.num_classes]) + # remove the background predictions + sub_predictions = predictions[:, 1:] + # choose the max score class + classes = tf.argmax(sub_predictions, axis=1) + 1 # class labels + scores = tf.reduce_max(sub_predictions, axis=1) # max_class scores + # Boxes selection: use threshold + filter_mask = scores > self.threshold + classes = tf.boolean_mask(classes, filter_mask) + scores = tf.boolean_mask(scores, filter_mask) + bboxes = tf.boolean_mask(bboxes, filter_mask) + return classes, scores, bboxes + + def _bboxes_select(self, predictions, locations): + """Select all bboxes predictions, only for bacth_size=1""" + anchor_bboxes_list = self.anchors() + classes_list = [] + scores_list = [] + bboxes_list = [] + # select bboxes for each feat layer + for n in range(len(predictions)): + anchor_bboxes = list(map(tf.convert_to_tensor, anchor_bboxes_list[n])) + classes, scores, bboxes = self._bboxes_select_layer(predictions[n], + locations[n], anchor_bboxes, self.ssd_params.prior_scaling) + classes_list.append(classes) + scores_list.append(scores) + bboxes_list.append(bboxes) + # combine all feat layers + classes = tf.concat(classes_list, axis=0) + scores = tf.concat(scores_list, axis=0) + bboxes = tf.concat(bboxes_list, axis=0) + return classes, scores, bboxes + + def images(self): + return self._images + + def detections(self): + return self._classes, self._scores, self._bboxes + + +if __name__ == "__main__": + ssd = SSD() + sess = tf.Session() + saver_ = tf.train.Saver() + saver_.restore(sess, "../SSD-Tensorflow-master/ssd_checkpoints/ssd_vgg_300_weights.ckpt") + diff --git a/ObjectDetections/SSD/ssd_anchors.py b/ObjectDetections/SSD/ssd_anchors.py new file mode 100644 index 0000000..a121f1f --- /dev/null +++ b/ObjectDetections/SSD/ssd_anchors.py @@ -0,0 +1,107 @@ +""" +SSD anchors +""" +import math + +import numpy as np + +def ssd_size_bounds_to_values(size_bounds, + n_feat_layers, + img_shape=(300, 300)): + """Compute the reference sizes of the anchor boxes from relative bounds. + The absolute values are measured in pixels, based on the network + default size (300 pixels). + + This function follows the computation performed in the original + implementation of SSD in Caffe. + + Return: + list of list containing the absolute sizes at each scale. For each scale, + the ratios only apply to the first value. + """ + assert img_shape[0] == img_shape[1] + + img_size = img_shape[0] + min_ratio = int(size_bounds[0] * 100) + max_ratio = int(size_bounds[1] * 100) + step = int(math.floor((max_ratio - min_ratio) / (n_feat_layers - 2))) + # Start with the following smallest sizes. + sizes = [[img_size * size_bounds[0] / 2, img_size * size_bounds[0]]] + for ratio in range(min_ratio, max_ratio + 1, step): + sizes.append((img_size * ratio / 100., + img_size * (ratio + step) / 100.)) + return sizes + +def ssd_anchor_one_layer(img_shape, + feat_shape, + sizes, + ratios, + step, + offset=0.5, + dtype=np.float32): + """Computer SSD default anchor boxes for one feature layer. + + Determine the relative position grid of the centers, and the relative + width and height. + + Arguments: + feat_shape: Feature shape, used for computing relative position grids; + size: Absolute reference sizes; + ratios: Ratios to use on these features; + img_shape: Image shape, used for computing height, width relatively to the + former; + offset: Grid offset. + + Return: + y, x, h, w: Relative x and y grids, and height and width. + """ + # Compute the position grid: simple way. + # y, x = np.mgrid[0:feat_shape[0], 0:feat_shape[1]] + # y = (y.astype(dtype) + offset) / feat_shape[0] + # x = (x.astype(dtype) + offset) / feat_shape[1] + # Weird SSD-Caffe computation using steps values... + y, x = np.mgrid[0:feat_shape[0], 0:feat_shape[1]] + y = (y.astype(dtype) + offset) * step / img_shape[0] + x = (x.astype(dtype) + offset) * step / img_shape[1] + + # Expand dims to support easy broadcasting. + y = np.expand_dims(y, axis=-1) # [size, size, 1] + x = np.expand_dims(x, axis=-1) # [size, size, 1] + + # Compute relative height and width. + # Tries to follow the original implementation of SSD for the order. + num_anchors = len(sizes) + len(ratios) + h = np.zeros((num_anchors, ), dtype=dtype) # [n_anchors] + w = np.zeros((num_anchors, ), dtype=dtype) # [n_anchors] + # Add first anchor boxes with ratio=1. + h[0] = sizes[0] / img_shape[0] + w[0] = sizes[0] / img_shape[1] + di = 1 + if len(sizes) > 1: + h[1] = math.sqrt(sizes[0] * sizes[1]) / img_shape[0] + w[1] = math.sqrt(sizes[0] * sizes[1]) / img_shape[1] + di += 1 + for i, r in enumerate(ratios): + h[i+di] = sizes[0] / img_shape[0] / math.sqrt(r) + w[i+di] = sizes[0] / img_shape[1] * math.sqrt(r) + return y, x, h, w + + +def ssd_anchors_all_layers(img_shape, + layers_shape, + anchor_sizes, + anchor_ratios, + anchor_steps, + offset=0.5, + dtype=np.float32): + """Compute anchor boxes for all feature layers. + """ + layers_anchors = [] + for i, s in enumerate(layers_shape): + anchor_bboxes = ssd_anchor_one_layer(img_shape, s, + anchor_sizes[i], + anchor_ratios[i], + anchor_steps[i], + offset=offset, dtype=dtype) + layers_anchors.append(anchor_bboxes) + return layers_anchors \ No newline at end of file diff --git a/ObjectDetections/SSD/ssd_layers.py b/ObjectDetections/SSD/ssd_layers.py new file mode 100644 index 0000000..071ffaa --- /dev/null +++ b/ObjectDetections/SSD/ssd_layers.py @@ -0,0 +1,61 @@ +""" +Layers for SSD +""" + +import tensorflow as tf + +# Conv2d: for stride = 1 +def conv2d(x, filters, kernel_size, stride=1, padding="same", + dilation_rate=1, activation=tf.nn.relu, scope="conv2d"): + kernel_sizes = [kernel_size] * 2 + strides = [stride] * 2 + dilation_rate = [dilation_rate] * 2 + return tf.layers.conv2d(x, filters, kernel_sizes, strides=strides, + dilation_rate=dilation_rate, padding=padding, + name=scope, activation=activation) + +# max pool2d: default pool_size = stride +def max_pool2d(x, pool_size, stride=None, scope="max_pool2d"): + pool_sizes = [pool_size] * 2 + strides = [pool_size] * 2 if stride is None else [stride] * 2 + return tf.layers.max_pooling2d(x, pool_sizes, strides, name=scope, padding="same") + +# pad2d: for conv2d with stride > 1 +def pad2d(x, pad): + return tf.pad(x, paddings=[[0, 0], [pad, pad], [pad, pad], [0, 0]]) + +# dropout +def dropout(x, rate=0.5, is_training=True): + return tf.layers.dropout(x, rate=rate, training=is_training) + +# l2norm (not bacth norm, spatial normalization) +def l2norm(x, scale, trainable=True, scope="L2Normalization"): + n_channels = x.get_shape().as_list()[-1] + l2_norm = tf.nn.l2_normalize(x, [3], epsilon=1e-12) + with tf.variable_scope(scope): + gamma = tf.get_variable("gamma", shape=[n_channels, ], dtype=tf.float32, + initializer=tf.constant_initializer(scale), + trainable=trainable) + return l2_norm * gamma + + +# multibox layer: get class and location predicitions from detection layer +def ssd_multibox_layer(x, num_classes, sizes, ratios, normalization=-1, scope="multibox"): + pre_shape = x.get_shape().as_list()[1:-1] + pre_shape = [-1] + pre_shape + with tf.variable_scope(scope): + # l2 norm + if normalization > 0: + x = l2norm(x, normalization) + print(x) + # numbers of anchors + n_anchors = len(sizes) + len(ratios) + # location predictions + loc_pred = conv2d(x, n_anchors*4, 3, activation=None, scope="conv_loc") + loc_pred = tf.reshape(loc_pred, pre_shape + [n_anchors, 4]) + # class prediction + cls_pred = conv2d(x, n_anchors*num_classes, 3, activation=None, scope="conv_cls") + cls_pred = tf.reshape(cls_pred, pre_shape + [n_anchors, num_classes]) + return cls_pred, loc_pred + + diff --git a/ObjectDetections/SSD/utils.py b/ObjectDetections/SSD/utils.py new file mode 100644 index 0000000..af73360 --- /dev/null +++ b/ObjectDetections/SSD/utils.py @@ -0,0 +1,130 @@ +""" +Help functions for SSD +""" + +import cv2 +import numpy as np + + +############## preprocess image ################## +# whiten the image +def whiten_image(image, means=(123., 117., 104.)): + """Subtracts the given means from each image channel""" + if image.ndim != 3: + raise ValueError('Input must be of size [height, width, C>0]') + num_channels = image.shape[-1] + if len(means) != num_channels: + raise ValueError('len(means) must match the number of channels') + + mean = np.array(means, dtype=image.dtype) + image = image - mean + return image + +def resize_image(image, size=(300, 300)): + return cv2.resize(image, size) + +def preprocess_image(image): + """Preprocess a image to inference""" + image_cp = np.copy(image).astype(np.float32) + # whiten the image + image_whitened = whiten_image(image_cp) + # resize the image + image_resized = resize_image(image_whitened) + # expand the batch_size dim + image_expanded = np.expand_dims(image_resized, axis=0) + return image_expanded + +############## process bboxes ################## +def bboxes_clip(bbox_ref, bboxes): + """Clip bounding boxes with respect to reference bbox. + """ + bboxes = np.copy(bboxes) + bboxes = np.transpose(bboxes) + bbox_ref = np.transpose(bbox_ref) + bboxes[0] = np.maximum(bboxes[0], bbox_ref[0]) + bboxes[1] = np.maximum(bboxes[1], bbox_ref[1]) + bboxes[2] = np.minimum(bboxes[2], bbox_ref[2]) + bboxes[3] = np.minimum(bboxes[3], bbox_ref[3]) + bboxes = np.transpose(bboxes) + return bboxes + +def bboxes_sort(classes, scores, bboxes, top_k=400): + """Sort bounding boxes by decreasing order and keep only the top_k + """ + # if priority_inside: + # inside = (bboxes[:, 0] > margin) & (bboxes[:, 1] > margin) & \ + # (bboxes[:, 2] < 1-margin) & (bboxes[:, 3] < 1-margin) + # idxes = np.argsort(-scores) + # inside = inside[idxes] + # idxes = np.concatenate([idxes[inside], idxes[~inside]]) + idxes = np.argsort(-scores) + classes = classes[idxes][:top_k] + scores = scores[idxes][:top_k] + bboxes = bboxes[idxes][:top_k] + return classes, scores, bboxes + +def bboxes_iou(bboxes1, bboxes2): + """Computing iou between bboxes1 and bboxes2. + Note: bboxes1 and bboxes2 can be multi-dimensional, but should broacastable. + """ + bboxes1 = np.transpose(bboxes1) + bboxes2 = np.transpose(bboxes2) + # Intersection bbox and volume. + int_ymin = np.maximum(bboxes1[0], bboxes2[0]) + int_xmin = np.maximum(bboxes1[1], bboxes2[1]) + int_ymax = np.minimum(bboxes1[2], bboxes2[2]) + int_xmax = np.minimum(bboxes1[3], bboxes2[3]) + + int_h = np.maximum(int_ymax - int_ymin, 0.) + int_w = np.maximum(int_xmax - int_xmin, 0.) + int_vol = int_h * int_w + # Union volume. + vol1 = (bboxes1[2] - bboxes1[0]) * (bboxes1[3] - bboxes1[1]) + vol2 = (bboxes2[2] - bboxes2[0]) * (bboxes2[3] - bboxes2[1]) + iou = int_vol / (vol1 + vol2 - int_vol) + return iou + +def bboxes_nms(classes, scores, bboxes, nms_threshold=0.5): + """Apply non-maximum selection to bounding boxes. + """ + keep_bboxes = np.ones(scores.shape, dtype=np.bool) + for i in range(scores.size-1): + if keep_bboxes[i]: + # Computer overlap with bboxes which are following. + overlap = bboxes_iou(bboxes[i], bboxes[(i+1):]) + # Overlap threshold for keeping + checking part of the same class + keep_overlap = np.logical_or(overlap < nms_threshold, classes[(i+1):] != classes[i]) + keep_bboxes[(i+1):] = np.logical_and(keep_bboxes[(i+1):], keep_overlap) + + idxes = np.where(keep_bboxes) + return classes[idxes], scores[idxes], bboxes[idxes] + +def bboxes_resize(bbox_ref, bboxes): + """Resize bounding boxes based on a reference bounding box, + assuming that the latter is [0, 0, 1, 1] after transform. + """ + bboxes = np.copy(bboxes) + # Translate. + bboxes[:, 0] -= bbox_ref[0] + bboxes[:, 1] -= bbox_ref[1] + bboxes[:, 2] -= bbox_ref[0] + bboxes[:, 3] -= bbox_ref[1] + # Resize. + resize = [bbox_ref[2] - bbox_ref[0], bbox_ref[3] - bbox_ref[1]] + bboxes[:, 0] /= resize[0] + bboxes[:, 1] /= resize[1] + bboxes[:, 2] /= resize[0] + bboxes[:, 3] /= resize[1] + return bboxes + +def process_bboxes(rclasses, rscores, rbboxes, rbbox_img = (0.0, 0.0, 1.0, 1.0), + top_k=400, nms_threshold=0.5): + """Process the bboxes including sort and nms""" + rbboxes = bboxes_clip(rbbox_img, rbboxes) + rclasses, rscores, rbboxes = bboxes_sort(rclasses, rscores, rbboxes, top_k) + rclasses, rscores, rbboxes = bboxes_nms(rclasses, rscores, rbboxes, nms_threshold) + rbboxes = bboxes_resize(rbbox_img, rbboxes) + return rclasses, rscores, rbboxes + + + diff --git a/ObjectDetections/SSD/var_name.txt b/ObjectDetections/SSD/var_name.txt new file mode 100644 index 0000000..fe2c4a3 --- /dev/null +++ b/ObjectDetections/SSD/var_name.txt @@ -0,0 +1,71 @@ +ssd_300_vgg/conv1_1/kernel +ssd_300_vgg/conv1_1/bias +ssd_300_vgg/conv1_2/kernel +ssd_300_vgg/conv1_2/bias +ssd_300_vgg/conv2_1/kernel +ssd_300_vgg/conv2_1/bias +ssd_300_vgg/conv2_2/kernel +ssd_300_vgg/conv2_2/bias +ssd_300_vgg/conv3_1/kernel +ssd_300_vgg/conv3_1/bias +ssd_300_vgg/conv3_2/kernel +ssd_300_vgg/conv3_2/bias +ssd_300_vgg/conv3_3/kernel +ssd_300_vgg/conv3_3/bias +ssd_300_vgg/conv4_1/kernel +ssd_300_vgg/conv4_1/bias +ssd_300_vgg/conv4_2/kernel +ssd_300_vgg/conv4_2/bias +ssd_300_vgg/conv4_3/kernel +ssd_300_vgg/conv4_3/bias +ssd_300_vgg/conv5_1/kernel +ssd_300_vgg/conv5_1/bias +ssd_300_vgg/conv5_2/kernel +ssd_300_vgg/conv5_2/bias +ssd_300_vgg/conv5_3/kernel +ssd_300_vgg/conv5_3/bias +ssd_300_vgg/conv6/kernel +ssd_300_vgg/conv6/bias +ssd_300_vgg/conv7/kernel +ssd_300_vgg/conv7/bias +ssd_300_vgg/conv8_1x1/kernel +ssd_300_vgg/conv8_1x1/bias +ssd_300_vgg/conv8_3x3/kernel +ssd_300_vgg/conv8_3x3/bias +ssd_300_vgg/conv9_1x1/kernel +ssd_300_vgg/conv9_1x1/bias +ssd_300_vgg/conv9_3x3/kernel +ssd_300_vgg/conv9_3x3/bias +ssd_300_vgg/conv10_1x1/kernel +ssd_300_vgg/conv10_1x1/bias +ssd_300_vgg/conv10_3x3/kernel +ssd_300_vgg/conv10_3x3/bias +ssd_300_vgg/conv11_1x1/kernel +ssd_300_vgg/conv11_1x1/bias +ssd_300_vgg/conv11_3x3/kernel +ssd_300_vgg/conv11_3x3/bias +ssd_300_vgg/block4_box/L2Normalization/gamma +ssd_300_vgg/block4_box/conv_loc/kernel +ssd_300_vgg/block4_box/conv_loc/bias +ssd_300_vgg/block4_box/conv_cls/kernel +ssd_300_vgg/block4_box/conv_cls/bias +ssd_300_vgg/block7_box/conv_loc/kernel +ssd_300_vgg/block7_box/conv_loc/bias +ssd_300_vgg/block7_box/conv_cls/kernel +ssd_300_vgg/block7_box/conv_cls/bias +ssd_300_vgg/block8_box/conv_loc/kernel +ssd_300_vgg/block8_box/conv_loc/bias +ssd_300_vgg/block8_box/conv_cls/kernel +ssd_300_vgg/block8_box/conv_cls/bias +ssd_300_vgg/block9_box/conv_loc/kernel +ssd_300_vgg/block9_box/conv_loc/bias +ssd_300_vgg/block9_box/conv_cls/kernel +ssd_300_vgg/block9_box/conv_cls/bias +ssd_300_vgg/block10_box/conv_loc/kernel +ssd_300_vgg/block10_box/conv_loc/bias +ssd_300_vgg/block10_box/conv_cls/kernel +ssd_300_vgg/block10_box/conv_cls/bias +ssd_300_vgg/block11_box/conv_loc/kernel +ssd_300_vgg/block11_box/conv_loc/bias +ssd_300_vgg/block11_box/conv_cls/kernel +ssd_300_vgg/block11_box/conv_cls/bias diff --git a/ObjectDetections/SSD/visualization.py b/ObjectDetections/SSD/visualization.py new file mode 100644 index 0000000..d6ace07 --- /dev/null +++ b/ObjectDetections/SSD/visualization.py @@ -0,0 +1,119 @@ +# Copyright 2017 Paul Balanca. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +import cv2 +import random + +import matplotlib.pyplot as plt +import matplotlib.image as mpimg +import matplotlib.cm as mpcm + + +# class names +CLASSES = ["aeroplane", "bicycle", "bird", "boat", "bottle", + "bus", "car", "cat", "chair", "cow", "diningtable", + "dog", "horse", "motorbike", "person", "pottedplant", + "sheep", "sofa", "train","tvmonitor"] +# =========================================================================== # +# Some colormaps. +# =========================================================================== # +def colors_subselect(colors, num_classes=21): + dt = len(colors) // num_classes + sub_colors = [] + for i in range(num_classes): + color = colors[i*dt] + if isinstance(color[0], float): + sub_colors.append([int(c * 255) for c in color]) + else: + sub_colors.append([c for c in color]) + return sub_colors + +colors_plasma = colors_subselect(mpcm.plasma.colors, num_classes=21) +colors_tableau = [(255, 255, 255), (31, 119, 180), (174, 199, 232), (255, 127, 14), (255, 187, 120), + (44, 160, 44), (152, 223, 138), (214, 39, 40), (255, 152, 150), + (148, 103, 189), (197, 176, 213), (140, 86, 75), (196, 156, 148), + (227, 119, 194), (247, 182, 210), (127, 127, 127), (199, 199, 199), + (188, 189, 34), (219, 219, 141), (23, 190, 207), (158, 218, 229)] + + +# =========================================================================== # +# OpenCV drawing. +# =========================================================================== # +def draw_lines(img, lines, color=[255, 0, 0], thickness=2): + """Draw a collection of lines on an image. + """ + for line in lines: + for x1, y1, x2, y2 in line: + cv2.line(img, (x1, y1), (x2, y2), color, thickness) + + +def draw_rectangle(img, p1, p2, color=[255, 0, 0], thickness=2): + cv2.rectangle(img, p1[::-1], p2[::-1], color, thickness) + + +def draw_bbox(img, bbox, shape, label, color=[255, 0, 0], thickness=2): + p1 = (int(bbox[0] * shape[0]), int(bbox[1] * shape[1])) + p2 = (int(bbox[2] * shape[0]), int(bbox[3] * shape[1])) + cv2.rectangle(img, p1[::-1], p2[::-1], color, thickness) + p1 = (p1[0]+15, p1[1]) + cv2.putText(img, str(label), p1[::-1], cv2.FONT_HERSHEY_DUPLEX, 0.5, color, 1) + + +def bboxes_draw_on_img(img, classes, scores, bboxes, colors, thickness=2): + shape = img.shape + for i in range(bboxes.shape[0]): + bbox = bboxes[i] + color = colors[classes[i]] + # Draw bounding box... + p1 = (int(bbox[0] * shape[0]), int(bbox[1] * shape[1])) + p2 = (int(bbox[2] * shape[0]), int(bbox[3] * shape[1])) + cv2.rectangle(img, p1[::-1], p2[::-1], color, thickness) + # Draw text... + s = '%s/%.3f' % (classes[i], scores[i]) + p1 = (p1[0]-5, p1[1]) + cv2.putText(img, s, p1[::-1], cv2.FONT_HERSHEY_DUPLEX, 0.4, color, 1) + + +# =========================================================================== # +# Matplotlib show... +# =========================================================================== # +def plt_bboxes(img, classes, scores, bboxes, figsize=(10,10), linewidth=1.5, show_class_name=True): + """Visualize bounding boxes. Largely inspired by SSD-MXNET! + """ + fig = plt.figure(figsize=figsize) + plt.imshow(img) + height = img.shape[0] + width = img.shape[1] + colors = dict() + for i in range(classes.shape[0]): + cls_id = int(classes[i]) + if cls_id >= 0: + score = scores[i] + if cls_id not in colors: + colors[cls_id] = (random.random(), random.random(), random.random()) + ymin = int(bboxes[i, 0] * height) + xmin = int(bboxes[i, 1] * width) + ymax = int(bboxes[i, 2] * height) + xmax = int(bboxes[i, 3] * width) + rect = plt.Rectangle((xmin, ymin), xmax - xmin, + ymax - ymin, fill=False, + edgecolor=colors[cls_id], + linewidth=linewidth) + plt.gca().add_patch(rect) + class_name = CLASSES[cls_id-1] if show_class_name else str(cls_id) + plt.gca().text(xmin, ymin - 2, + '{:s} | {:.3f}'.format(class_name, score), + bbox=dict(facecolor=colors[cls_id], alpha=0.5), + fontsize=12, color='white') + plt.show() diff --git a/ObjectDetections/yolo/test_images/car.jpg b/ObjectDetections/yolo/test_images/car.jpg new file mode 100644 index 0000000..8c24a69 Binary files /dev/null and b/ObjectDetections/yolo/test_images/car.jpg differ diff --git a/ObjectDetections/yolo/test_images/cat.jpg b/ObjectDetections/yolo/test_images/cat.jpg new file mode 100644 index 0000000..f4f2e76 Binary files /dev/null and b/ObjectDetections/yolo/test_images/cat.jpg differ diff --git a/ObjectDetections/yolo/test_images/person.jpg b/ObjectDetections/yolo/test_images/person.jpg new file mode 100644 index 0000000..61d377f Binary files /dev/null and b/ObjectDetections/yolo/test_images/person.jpg differ diff --git a/ObjectDetections/yolo/yolo.py b/ObjectDetections/yolo/yolo.py new file mode 100644 index 0000000..5fa6240 --- /dev/null +++ b/ObjectDetections/yolo/yolo.py @@ -0,0 +1,259 @@ +""" +Yolo V1 by tensorflow +""" + +import numpy as np +import tensorflow as tf +import cv2 + + +def leak_relu(x, alpha=0.1): + return tf.maximum(alpha * x, x) + +class Yolo(object): + def __init__(self, weights_file): + self.verbose = True + # detection params + self.S = 7 # cell size + self.B = 2 # boxes_per_cell + self.classes = ["aeroplane", "bicycle", "bird", "boat", "bottle", + "bus", "car", "cat", "chair", "cow", "diningtable", + "dog", "horse", "motorbike", "person", "pottedplant", + "sheep", "sofa", "train","tvmonitor"] + self.C = len(self.classes) # number of classes + # offset for box center (top left point of each cell) + self.x_offset = np.transpose(np.reshape(np.array([np.arange(self.S)]*self.S*self.B), + [self.B, self.S, self.S]), [1, 2, 0]) + self.y_offset = np.transpose(self.x_offset, [1, 0, 2]) + + self.threshold = 0.2 # confidence scores threshold + self.iou_threshold = 0.5 + + self.sess = tf.Session() + self._build_net() + self._load_weights(weights_file) + + def _build_net(self): + """build the network""" + if self.verbose: + print("Start to build the network ...") + self.images = tf.placeholder(tf.float32, [None, 448, 448, 3]) + net = self._conv_layer(self.images, 1, 64, 7, 2) + net = self._maxpool_layer(net, 1, 2, 2) + net = self._conv_layer(net, 2, 192, 3, 1) + net = self._maxpool_layer(net, 2, 2, 2) + net = self._conv_layer(net, 3, 128, 1, 1) + net = self._conv_layer(net, 4, 256, 3, 1) + net = self._conv_layer(net, 5, 256, 1, 1) + net = self._conv_layer(net, 6, 512, 3, 1) + net = self._maxpool_layer(net, 6, 2, 2) + net = self._conv_layer(net, 7, 256, 1, 1) + net = self._conv_layer(net, 8, 512, 3, 1) + net = self._conv_layer(net, 9, 256, 1, 1) + net = self._conv_layer(net, 10, 512, 3, 1) + net = self._conv_layer(net, 11, 256, 1, 1) + net = self._conv_layer(net, 12, 512, 3, 1) + net = self._conv_layer(net, 13, 256, 1, 1) + net = self._conv_layer(net, 14, 512, 3, 1) + net = self._conv_layer(net, 15, 512, 1, 1) + net = self._conv_layer(net, 16, 1024, 3, 1) + net = self._maxpool_layer(net, 16, 2, 2) + net = self._conv_layer(net, 17, 512, 1, 1) + net = self._conv_layer(net, 18, 1024, 3, 1) + net = self._conv_layer(net, 19, 512, 1, 1) + net = self._conv_layer(net, 20, 1024, 3, 1) + net = self._conv_layer(net, 21, 1024, 3, 1) + net = self._conv_layer(net, 22, 1024, 3, 2) + net = self._conv_layer(net, 23, 1024, 3, 1) + net = self._conv_layer(net, 24, 1024, 3, 1) + net = self._flatten(net) + net = self._fc_layer(net, 25, 512, activation=leak_relu) + net = self._fc_layer(net, 26, 4096, activation=leak_relu) + net = self._fc_layer(net, 27, self.S*self.S*(self.C+5*self.B)) + self.predicts = net + + def _conv_layer(self, x, id, num_filters, filter_size, stride): + """Conv layer""" + in_channels = x.get_shape().as_list()[-1] + weight = tf.Variable(tf.truncated_normal([filter_size, filter_size, + in_channels, num_filters], stddev=0.1)) + bias = tf.Variable(tf.zeros([num_filters,])) + # padding, note: not using padding="SAME" + pad_size = filter_size // 2 + pad_mat = np.array([[0, 0], [pad_size, pad_size], [pad_size, pad_size], [0, 0]]) + x_pad = tf.pad(x, pad_mat) + conv = tf.nn.conv2d(x_pad, weight, strides=[1, stride, stride, 1], padding="VALID") + output = leak_relu(tf.nn.bias_add(conv, bias)) + if self.verbose: + print(" Layer %d: type=Conv, num_filter=%d, filter_size=%d, stride=%d, output_shape=%s" \ + % (id, num_filters, filter_size, stride, str(output.get_shape()))) + return output + + def _fc_layer(self, x, id, num_out, activation=None): + """fully connected layer""" + num_in = x.get_shape().as_list()[-1] + weight = tf.Variable(tf.truncated_normal([num_in, num_out], stddev=0.1)) + bias = tf.Variable(tf.zeros([num_out,])) + output = tf.nn.xw_plus_b(x, weight, bias) + if activation: + output = activation(output) + if self.verbose: + print(" Layer %d: type=Fc, num_out=%d, output_shape=%s" \ + % (id, num_out, str(output.get_shape()))) + return output + + def _maxpool_layer(self, x, id, pool_size, stride): + output = tf.nn.max_pool(x, [1, pool_size, pool_size, 1], + strides=[1, stride, stride, 1], padding="SAME") + if self.verbose: + print(" Layer %d: type=MaxPool, pool_size=%d, stride=%d, output_shape=%s" \ + % (id, pool_size, stride, str(output.get_shape()))) + return output + + def _flatten(self, x): + """flatten the x""" + tran_x = tf.transpose(x, [0, 3, 1, 2]) # channle first mode + nums = np.product(x.get_shape().as_list()[1:]) + return tf.reshape(tran_x, [-1, nums]) + + def _load_weights(self, weights_file): + """Load weights from file""" + if self.verbose: + print("Start to load weights from file:%s" % (weights_file)) + saver = tf.train.Saver() + saver.restore(self.sess, weights_file) + + def detect_from_file(self, image_file, imshow=True, deteted_boxes_file="boxes.txt", + detected_image_file="detected_image.jpg"): + """Do detection given a image file""" + # read image + image = cv2.imread(image_file) + img_h, img_w, _ = image.shape + predicts = self._detect_from_image(image) + predict_boxes = self._interpret_predicts(predicts, img_h, img_w) + self.show_results(image, predict_boxes, imshow, deteted_boxes_file, detected_image_file) + + def _detect_from_image(self, image): + """Do detection given a cv image""" + img_resized = cv2.resize(image, (448, 448)) + img_RGB = cv2.cvtColor(img_resized, cv2.COLOR_BGR2RGB) + img_resized_np = np.asarray(img_RGB) + _images = np.zeros((1, 448, 448, 3), dtype=np.float32) + _images[0] = (img_resized_np / 255.0) * 2.0 - 1.0 + predicts = self.sess.run(self.predicts, feed_dict={self.images: _images})[0] + return predicts + + def _interpret_predicts(self, predicts, img_h, img_w): + """Interpret the predicts and get the detetction boxes""" + idx1 = self.S*self.S*self.C + idx2 = idx1 + self.S*self.S*self.B + # class prediction + class_probs = np.reshape(predicts[:idx1], [self.S, self.S, self.C]) + # confidence + confs = np.reshape(predicts[idx1:idx2], [self.S, self.S, self.B]) + # boxes -> (x, y, w, h) + boxes = np.reshape(predicts[idx2:], [self.S, self.S, self.B, 4]) + + # convert the x, y to the coordinates relative to the top left point of the image + boxes[:, :, :, 0] += self.x_offset + boxes[:, :, :, 1] += self.y_offset + boxes[:, :, :, :2] /= self.S + + # the predictions of w, h are the square root + boxes[:, :, :, 2:] = np.square(boxes[:, :, :, 2:]) + + # multiply the width and height of image + boxes[:, :, :, 0] *= img_w + boxes[:, :, :, 1] *= img_h + boxes[:, :, :, 2] *= img_w + boxes[:, :, :, 3] *= img_h + + # class-specific confidence scores [S, S, B, C] + scores = np.expand_dims(confs, -1) * np.expand_dims(class_probs, 2) + + scores = np.reshape(scores, [-1, self.C]) # [S*S*B, C] + boxes = np.reshape(boxes, [-1, 4]) # [S*S*B, 4] + + # filter the boxes when score < threhold + scores[scores < self.threshold] = 0.0 + + # non max suppression + self._non_max_suppression(scores, boxes) + + # report the boxes + predict_boxes = [] # (class, x, y, w, h, scores) + max_idxs = np.argmax(scores, axis=1) + for i in range(len(scores)): + max_idx = max_idxs[i] + if scores[i, max_idx] > 0.0: + predict_boxes.append((self.classes[max_idx], boxes[i, 0], boxes[i, 1], + boxes[i, 2], boxes[i, 3], scores[i, max_idx])) + return predict_boxes + + def _non_max_suppression(self, scores, boxes): + """Non max suppression""" + # for each class + for c in range(self.C): + sorted_idxs = np.argsort(scores[:, c]) + last = len(sorted_idxs) - 1 + while last > 0: + if scores[sorted_idxs[last], c] < 1e-6: + break + for i in range(last): + if scores[sorted_idxs[i], c] < 1e-6: + continue + if self._iou(boxes[sorted_idxs[i]], boxes[sorted_idxs[last]]) > self.iou_threshold: + scores[sorted_idxs[i], c] = 0.0 + last -= 1 + + def _iou(self, box1, box2): + """Compute the iou of two boxes""" + + inter_w = np.minimum(box1[0]+0.5*box1[2], box2[0]+0.5*box2[2]) - \ + np.maximum(box1[0]-0.5*box2[2], box2[0]-0.5*box2[2]) + inter_h = np.minimum(box1[1]+0.5*box1[3], box2[1]+0.5*box2[3]) - \ + np.maximum(box1[1]-0.5*box2[3], box2[1]-0.5*box2[3]) + if inter_h < 0 or inter_w < 0: + inter = 0 + else: + inter = inter_w * inter_h + union = box1[2]*box1[3] + box2[2]*box2[3] - inter + return inter / union + + def show_results(self, image, results, imshow=True, deteted_boxes_file=None, + detected_image_file=None): + """Show the detection boxes""" + img_cp = image.copy() + if deteted_boxes_file: + f = open(deteted_boxes_file, "w") + # draw boxes + for i in range(len(results)): + x = int(results[i][1]) + y = int(results[i][2]) + w = int(results[i][3]) // 2 + h = int(results[i][4]) // 2 + if self.verbose: + print(" class: %s, [x, y, w, h]=[%d, %d, %d, %d], confidence=%f" % (results[i][0], + x, y, w, h, results[i][-1])) + + cv2.rectangle(img_cp, (x - w, y - h), (x + w, y + h), (0, 255, 0), 2) + cv2.rectangle(img_cp, (x - w, y - h - 20), (x + w, y - h), (125, 125, 125), -1) + cv2.putText(img_cp, results[i][0] + ' : %.2f' % results[i][5], (x - w + 5, y - h - 7), + cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1) + if deteted_boxes_file: + f.write(results[i][0] + ',' + str(x) + ',' + str(y) + ',' + + str(w) + ',' + str(h)+',' + str(results[i][5]) + '\n') + if imshow: + cv2.imshow('YOLO_small detection', img_cp) + cv2.waitKey(1) + if detected_image_file: + cv2.imwrite(detected_image_file, img_cp) + if deteted_boxes_file: + f.close() + +if __name__ == "__main__": + yolo_net = Yolo("./weights/YOLO_small.ckpt") + yolo_net.detect_from_file("./test/car.jpg") + + + diff --git a/ObjectDetections/yolo/yolo_tf.py b/ObjectDetections/yolo/yolo_tf.py new file mode 100644 index 0000000..24b32cb --- /dev/null +++ b/ObjectDetections/yolo/yolo_tf.py @@ -0,0 +1,237 @@ +""" +Yolo V1 by tensorflow +""" + +import numpy as np +import tensorflow as tf +import cv2 + + +def leak_relu(x, alpha=0.1): + return tf.maximum(alpha * x, x) + +class Yolo(object): + def __init__(self, weights_file, verbose=True): + self.verbose = verbose + # detection params + self.S = 7 # cell size + self.B = 2 # boxes_per_cell + self.classes = ["aeroplane", "bicycle", "bird", "boat", "bottle", + "bus", "car", "cat", "chair", "cow", "diningtable", + "dog", "horse", "motorbike", "person", "pottedplant", + "sheep", "sofa", "train","tvmonitor"] + self.C = len(self.classes) # number of classes + # offset for box center (top left point of each cell) + self.x_offset = np.transpose(np.reshape(np.array([np.arange(self.S)]*self.S*self.B), + [self.B, self.S, self.S]), [1, 2, 0]) + self.y_offset = np.transpose(self.x_offset, [1, 0, 2]) + + self.threshold = 0.2 # confidence scores threhold + self.iou_threshold = 0.4 + # the maximum number of boxes to be selected by non max suppression + self.max_output_size = 10 + + self.sess = tf.Session() + self._build_net() + self._build_detector() + self._load_weights(weights_file) + + def _build_net(self): + """build the network""" + if self.verbose: + print("Start to build the network ...") + self.images = tf.placeholder(tf.float32, [None, 448, 448, 3]) + net = self._conv_layer(self.images, 1, 64, 7, 2) + net = self._maxpool_layer(net, 1, 2, 2) + net = self._conv_layer(net, 2, 192, 3, 1) + net = self._maxpool_layer(net, 2, 2, 2) + net = self._conv_layer(net, 3, 128, 1, 1) + net = self._conv_layer(net, 4, 256, 3, 1) + net = self._conv_layer(net, 5, 256, 1, 1) + net = self._conv_layer(net, 6, 512, 3, 1) + net = self._maxpool_layer(net, 6, 2, 2) + net = self._conv_layer(net, 7, 256, 1, 1) + net = self._conv_layer(net, 8, 512, 3, 1) + net = self._conv_layer(net, 9, 256, 1, 1) + net = self._conv_layer(net, 10, 512, 3, 1) + net = self._conv_layer(net, 11, 256, 1, 1) + net = self._conv_layer(net, 12, 512, 3, 1) + net = self._conv_layer(net, 13, 256, 1, 1) + net = self._conv_layer(net, 14, 512, 3, 1) + net = self._conv_layer(net, 15, 512, 1, 1) + net = self._conv_layer(net, 16, 1024, 3, 1) + net = self._maxpool_layer(net, 16, 2, 2) + net = self._conv_layer(net, 17, 512, 1, 1) + net = self._conv_layer(net, 18, 1024, 3, 1) + net = self._conv_layer(net, 19, 512, 1, 1) + net = self._conv_layer(net, 20, 1024, 3, 1) + net = self._conv_layer(net, 21, 1024, 3, 1) + net = self._conv_layer(net, 22, 1024, 3, 2) + net = self._conv_layer(net, 23, 1024, 3, 1) + net = self._conv_layer(net, 24, 1024, 3, 1) + net = self._flatten(net) + net = self._fc_layer(net, 25, 512, activation=leak_relu) + net = self._fc_layer(net, 26, 4096, activation=leak_relu) + net = self._fc_layer(net, 27, self.S*self.S*(self.C+5*self.B)) + self.predicts = net + + def _build_detector(self): + """Interpret the net output and get the predicted boxes""" + # the width and height of orignal image + self.width = tf.placeholder(tf.float32, name="img_w") + self.height = tf.placeholder(tf.float32, name="img_h") + # get class prob, confidence, boxes from net output + idx1 = self.S * self.S * self.C + idx2 = idx1 + self.S * self.S * self.B + # class prediction + class_probs = tf.reshape(self.predicts[0, :idx1], [self.S, self.S, self.C]) + # confidence + confs = tf.reshape(self.predicts[0, idx1:idx2], [self.S, self.S, self.B]) + # boxes -> (x, y, w, h) + boxes = tf.reshape(self.predicts[0, idx2:], [self.S, self.S, self.B, 4]) + + # convert the x, y to the coordinates relative to the top left point of the image + # the predictions of w, h are the square root + # multiply the width and height of image + boxes = tf.stack([(boxes[:, :, :, 0] + tf.constant(self.x_offset, dtype=tf.float32)) / self.S * self.width, + (boxes[:, :, :, 1] + tf.constant(self.y_offset, dtype=tf.float32)) / self.S * self.height, + tf.square(boxes[:, :, :, 2]) * self.width, + tf.square(boxes[:, :, :, 3]) * self.height], axis=3) + + # class-specific confidence scores [S, S, B, C] + scores = tf.expand_dims(confs, -1) * tf.expand_dims(class_probs, 2) + + scores = tf.reshape(scores, [-1, self.C]) # [S*S*B, C] + boxes = tf.reshape(boxes, [-1, 4]) # [S*S*B, 4] + + # find each box class, only select the max score + box_classes = tf.argmax(scores, axis=1) + box_class_scores = tf.reduce_max(scores, axis=1) + + # filter the boxes by the score threshold + filter_mask = box_class_scores >= self.threshold + scores = tf.boolean_mask(box_class_scores, filter_mask) + boxes = tf.boolean_mask(boxes, filter_mask) + box_classes = tf.boolean_mask(box_classes, filter_mask) + + # non max suppression (do not distinguish different classes) + # ref: https://tensorflow.google.cn/api_docs/python/tf/image/non_max_suppression + # box (x, y, w, h) -> box (x1, y1, x2, y2) + _boxes = tf.stack([boxes[:, 0] - 0.5 * boxes[:, 2], boxes[:, 1] - 0.5 * boxes[:, 3], + boxes[:, 0] + 0.5 * boxes[:, 2], boxes[:, 1] + 0.5 * boxes[:, 3]], axis=1) + nms_indices = tf.image.non_max_suppression(_boxes, scores, + self.max_output_size, self.iou_threshold) + self.scores = tf.gather(scores, nms_indices) + self.boxes = tf.gather(boxes, nms_indices) + self.box_classes = tf.gather(box_classes, nms_indices) + + def _conv_layer(self, x, id, num_filters, filter_size, stride): + """Conv layer""" + in_channels = x.get_shape().as_list()[-1] + weight = tf.Variable(tf.truncated_normal([filter_size, filter_size, + in_channels, num_filters], stddev=0.1)) + bias = tf.Variable(tf.zeros([num_filters,])) + # padding, note: not using padding="SAME" + pad_size = filter_size // 2 + pad_mat = np.array([[0, 0], [pad_size, pad_size], [pad_size, pad_size], [0, 0]]) + x_pad = tf.pad(x, pad_mat) + conv = tf.nn.conv2d(x_pad, weight, strides=[1, stride, stride, 1], padding="VALID") + output = leak_relu(tf.nn.bias_add(conv, bias)) + if self.verbose: + print(" Layer %d: type=Conv, num_filter=%d, filter_size=%d, stride=%d, output_shape=%s" \ + % (id, num_filters, filter_size, stride, str(output.get_shape()))) + return output + + def _fc_layer(self, x, id, num_out, activation=None): + """fully connected layer""" + num_in = x.get_shape().as_list()[-1] + weight = tf.Variable(tf.truncated_normal([num_in, num_out], stddev=0.1)) + bias = tf.Variable(tf.zeros([num_out,])) + output = tf.nn.xw_plus_b(x, weight, bias) + if activation: + output = activation(output) + if self.verbose: + print(" Layer %d: type=Fc, num_out=%d, output_shape=%s" \ + % (id, num_out, str(output.get_shape()))) + return output + + def _maxpool_layer(self, x, id, pool_size, stride): + output = tf.nn.max_pool(x, [1, pool_size, pool_size, 1], + strides=[1, stride, stride, 1], padding="SAME") + if self.verbose: + print(" Layer %d: type=MaxPool, pool_size=%d, stride=%d, output_shape=%s" \ + % (id, pool_size, stride, str(output.get_shape()))) + return output + + def _flatten(self, x): + """flatten the x""" + tran_x = tf.transpose(x, [0, 3, 1, 2]) # channle first mode + nums = np.product(x.get_shape().as_list()[1:]) + return tf.reshape(tran_x, [-1, nums]) + + def _load_weights(self, weights_file): + """Load weights from file""" + if self.verbose: + print("Start to load weights from file:%s" % (weights_file)) + saver = tf.train.Saver() + saver.restore(self.sess, weights_file) + + def detect_from_file(self, image_file, imshow=True, deteted_boxes_file="boxes.txt", + detected_image_file="detected_image.jpg"): + """Do detection given a image file""" + # read image + image = cv2.imread(image_file) + img_h, img_w, _ = image.shape + scores, boxes, box_classes = self._detect_from_image(image) + predict_boxes = [] + for i in range(len(scores)): + predict_boxes.append((self.classes[box_classes[i]], boxes[i, 0], + boxes[i, 1], boxes[i, 2], boxes[i, 3], scores[i])) + self.show_results(image, predict_boxes, imshow, deteted_boxes_file, detected_image_file) + + def _detect_from_image(self, image): + """Do detection given a cv image""" + img_h, img_w, _ = image.shape + img_resized = cv2.resize(image, (448, 448)) + img_RGB = cv2.cvtColor(img_resized, cv2.COLOR_BGR2RGB) + img_resized_np = np.asarray(img_RGB) + _images = np.zeros((1, 448, 448, 3), dtype=np.float32) + _images[0] = (img_resized_np / 255.0) * 2.0 - 1.0 + scores, boxes, box_classes = self.sess.run([self.scores, self.boxes, self.box_classes], + feed_dict={self.images: _images, self.width: img_w, self.height: img_h}) + return scores, boxes, box_classes + + def show_results(self, image, results, imshow=True, deteted_boxes_file=None, + detected_image_file=None): + """Show the detection boxes""" + img_cp = image.copy() + if deteted_boxes_file: + f = open(deteted_boxes_file, "w") + # draw boxes + for i in range(len(results)): + x = int(results[i][1]) + y = int(results[i][2]) + w = int(results[i][3]) // 2 + h = int(results[i][4]) // 2 + if self.verbose: + print(" class: %s, [x, y, w, h]=[%d, %d, %d, %d], confidence=%f" % (results[i][0], + x, y, w, h, results[i][-1])) + + cv2.rectangle(img_cp, (x - w, y - h), (x + w, y + h), (0, 255, 0), 2) + cv2.rectangle(img_cp, (x - w, y - h - 20), (x + w, y - h), (125, 125, 125), -1) + cv2.putText(img_cp, results[i][0] + ' : %.2f' % results[i][5], (x - w + 5, y - h - 7), + cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1) + if deteted_boxes_file: + f.write(results[i][0] + ',' + str(x) + ',' + str(y) + ',' + + str(w) + ',' + str(h)+',' + str(results[i][5]) + '\n') + if imshow: + cv2.imshow('YOLO_small detection', img_cp) + cv2.waitKey(1) + if detected_image_file: + cv2.imwrite(detected_image_file, img_cp) + if deteted_boxes_file: + f.close() + +if __name__ == "__main__": + yolo_net = Yolo("./weights/YOLO_small.ckpt") + yolo_net.detect_from_file("./test/car.jpg") diff --git a/ObjectDetections/yolo2/config.py b/ObjectDetections/yolo2/config.py new file mode 100644 index 0000000..ad7fa91 --- /dev/null +++ b/ObjectDetections/yolo2/config.py @@ -0,0 +1,25 @@ +""" +Yolov2 anchors and coco classes +""" + +""" +anchors = [[0.738768, 0.874946], + [2.42204, 2.65704], + [4.30971, 7.04493], + [10.246, 4.59428], + [12.6868, 11.8741]] +""" +anchors = [[0.57273, 0.677385], + [1.87446, 2.06253], + [3.33843, 5.47434], + [7.88282, 3.52778], + [9.77052, 9.16828]] + +def read_coco_labels(): + f = open("./data/coco_classes.txt") + class_names = [] + for l in f.readlines(): + class_names.append(l[:-1]) + return class_names + +class_names = read_coco_labels() \ No newline at end of file diff --git a/ObjectDetections/yolo2/data/coco_classes.txt b/ObjectDetections/yolo2/data/coco_classes.txt new file mode 100644 index 0000000..ca76c80 --- /dev/null +++ b/ObjectDetections/yolo2/data/coco_classes.txt @@ -0,0 +1,80 @@ +person +bicycle +car +motorbike +aeroplane +bus +train +truck +boat +traffic light +fire hydrant +stop sign +parking meter +bench +bird +cat +dog +horse +sheep +cow +elephant +bear +zebra +giraffe +backpack +umbrella +handbag +tie +suitcase +frisbee +skis +snowboard +sports ball +kite +baseball bat +baseball glove +skateboard +surfboard +tennis racket +bottle +wine glass +cup +fork +knife +spoon +bowl +banana +apple +sandwich +orange +broccoli +carrot +hot dog +pizza +donut +cake +chair +sofa +pottedplant +bed +diningtable +toilet +tvmonitor +laptop +mouse +remote +keyboard +cell phone +microwave +oven +toaster +sink +refrigerator +book +clock +vase +scissors +teddy bear +hair drier +toothbrush diff --git a/ObjectDetections/yolo2/demo.py b/ObjectDetections/yolo2/demo.py new file mode 100644 index 0000000..4a7183c --- /dev/null +++ b/ObjectDetections/yolo2/demo.py @@ -0,0 +1,50 @@ +""" +Demo for yolov2 +""" + +import numpy as np +import tensorflow as tf +import cv2 +from PIL import Image + +from model import darknet +from detect_ops import decode +from utils import preprocess_image, postprocess, draw_detection +from config import anchors, class_names + + +input_size = (416, 416) +image_file = "./images/car.jpg" +image = cv2.imread(image_file) +image_shape = image.shape[:2] +image_cp = preprocess_image(image, input_size) +""" +image = Image.open(image_file) +image_cp = image.resize(input_size, Image.BICUBIC) +image_cp = np.array(image_cp, dtype=np.float32)/255.0 +image_cp = np.expand_dims(image_cp, 0) +#print(image_cp) +""" + + +images = tf.placeholder(tf.float32, [1, input_size[0], input_size[1], 3]) +detection_feat = darknet(images) +feat_sizes = input_size[0] // 32, input_size[1] // 32 +detection_results = decode(detection_feat, feat_sizes, len(class_names), anchors) + +checkpoint_path = "./checkpoint_dir/yolo2_coco.ckpt" +saver = tf.train.Saver() +with tf.Session() as sess: + saver.restore(sess, checkpoint_path) + bboxes, obj_probs, class_probs = sess.run(detection_results, feed_dict={images: image_cp}) + +bboxes, scores, class_inds = postprocess(bboxes, obj_probs, class_probs, + image_shape=image_shape) +img_detection = draw_detection(image, bboxes, scores, class_inds, class_names) +cv2.imwrite("detection.jpg", img_detection) +cv2.imshow("detection results", img_detection) + +cv2.waitKey(0) + + + diff --git a/ObjectDetections/yolo2/detect_ops.py b/ObjectDetections/yolo2/detect_ops.py new file mode 100644 index 0000000..6060ece --- /dev/null +++ b/ObjectDetections/yolo2/detect_ops.py @@ -0,0 +1,39 @@ +""" +Detection ops for Yolov2 +""" + +import tensorflow as tf +import numpy as np + + +def decode(detection_feat, feat_sizes=(13, 13), num_classes=80, + anchors=None): + """decode from the detection feature""" + H, W = feat_sizes + num_anchors = len(anchors) + detetion_results = tf.reshape(detection_feat, [-1, H * W, num_anchors, + num_classes + 5]) + + bbox_xy = tf.nn.sigmoid(detetion_results[:, :, :, 0:2]) + bbox_wh = tf.exp(detetion_results[:, :, :, 2:4]) + obj_probs = tf.nn.sigmoid(detetion_results[:, :, :, 4]) + class_probs = tf.nn.softmax(detetion_results[:, :, :, 5:]) + + anchors = tf.constant(anchors, dtype=tf.float32) + + height_ind = tf.range(H, dtype=tf.float32) + width_ind = tf.range(W, dtype=tf.float32) + x_offset, y_offset = tf.meshgrid(height_ind, width_ind) + x_offset = tf.reshape(x_offset, [1, -1, 1]) + y_offset = tf.reshape(y_offset, [1, -1, 1]) + + # decode + bbox_x = (bbox_xy[:, :, :, 0] + x_offset) / W + bbox_y = (bbox_xy[:, :, :, 1] + y_offset) / H + bbox_w = bbox_wh[:, :, :, 0] * anchors[:, 0] / W * 0.5 + bbox_h = bbox_wh[:, :, :, 1] * anchors[:, 1] / H * 0.5 + + bboxes = tf.stack([bbox_x - bbox_w, bbox_y - bbox_h, + bbox_x + bbox_w, bbox_y + bbox_h], axis=3) + + return bboxes, obj_probs, class_probs diff --git a/ObjectDetections/yolo2/loss.py b/ObjectDetections/yolo2/loss.py new file mode 100644 index 0000000..931359f --- /dev/null +++ b/ObjectDetections/yolo2/loss.py @@ -0,0 +1,86 @@ +""" +Loss function for YOLOv2 +""" + +import numpy as np +import tensorflow as tf + +def compute_loss(predictions, targets, anchors, scales, num_classes=20, feat_sizes=(13, 13)): + """ + Compute the loss of Yolov2 for training + """ + H, W = feat_sizes + C = num_classes + B = len(anchors) + anchors = tf.constant(anchors, dtype=tf.float32) + anchors = tf.reshape(anchors, [1, 1, B, 2]) + + sprob, sconf, snoob, scoor = scales # the scales for different parts + + _coords = targets["coords"] # ground truth [-1, H*W, B, 4] + _probs = targets["probs"] # class probability [-1, H*W, B, C] one hot + _confs = targets["confs"] # 1 for object, 0 for background, [-1, H*W, B] + + # decode the net output + predictions = tf.reshape(predictions, [-1, H, W, B, (5 + C)]) + coords = predictions[:, :, :, :, 0:4] # t_x, t_y, t_w, t_h + coords = tf.reshape(coords, [-1, H*W, B, 4]) + coords_xy = tf.nn.sigmoid(coords[:, :, :, 0:2]) # (0, 1) relative cell top left + coords_wh = tf.sqrt(tf.exp(coords[:, :, :, 2:4]) * anchors / + np.reshape([W, H], [1, 1, 1, 2])) # sqrt of w, h (0, 1) + coords = tf.concat([coords_xy, coords_wh], axis=3) # [batch_size, H*W, B, 4] + + confs = tf.nn.sigmoid(predictions[:, :, :, :, 4]) # object confidence + confs = tf.reshape(confs, [-1, H*W, B, 1]) + + probs = tf.nn.softmax(predictions[:, :, :, :, 5:]) # class probability + probs = tf.reshape(probs, [-1, H*W, B, C]) + + preds = tf.concat([coords, confs, probs], axis=3) # [-1, H*W, B, (4+1+C)] + + # match ground truths with anchors (predictions in fact) + # assign ground truths to the predictions with the best IOU (select 1 among 5 anchors) + wh = tf.pow(coords[:, :, :, 2:4], 2) * np.reshape([W, H], [1, 1, 1, 2]) + areas = wh[:, :, :, 0] * wh[:, :, :, 1] + centers = coords[:, :, :, 0:2] + up_left, down_right = centers - (wh * 0.5), centers + (wh * 0.5) + + # the ground truth + _wh = tf.pow(_coords[:, :, :, 2:4], 2) * np.reshape([W, H], [1, 1, 1, 2]) + _areas = _wh[:, :, :, 0] * _wh[:, :, :, 1] + _centers = _coords[:, :, :, 0:2] + _up_left, _down_right = _centers - (_wh * 0.5), _centers + (_wh * 0.5) + + # compute IOU + inter_upleft = tf.maximum(up_left, _up_left) + inter_downright = tf.minimum(down_right, _down_right) + inter_wh = tf.maximum(inter_downright - inter_upleft, 0.0) + intersects = inter_wh[:, :, :, 0] * inter_wh[:, :, :, 1] + ious = tf.truediv(intersects, areas + _areas - intersects) + + best_iou_mask = tf.equal(ious, tf.reduce_max(ious, axis=2, keep_dims=True)) + best_iou_mask = tf.cast(best_iou_mask, tf.float32) + mask = best_iou_mask * _confs # [-1, H*W, B] + mask = tf.expand_dims(mask, -1) # [-1, H*W, B, 1] + + # compute weight terms + confs_w = snoob * (1 - mask) + sconf * mask + coords_w = scoor * mask + probs_w = sprob * mask + weights = tf.concat([coords_w, confs_w, probs_w], axis=3) + + truths = tf.concat([_coords, tf.expand_dims(_confs, -1), _probs], 3) + + loss = tf.pow(preds - truths, 2) * weights + loss = tf.reduce_sum(loss, axis=[1, 2, 3]) + loss = 0.5 * tf.reduce_mean(loss) + return loss + + + + + + + + + diff --git a/ObjectDetections/yolo2/model.png b/ObjectDetections/yolo2/model.png new file mode 100644 index 0000000..07ab142 Binary files /dev/null and b/ObjectDetections/yolo2/model.png differ diff --git a/ObjectDetections/yolo2/model.py b/ObjectDetections/yolo2/model.py new file mode 100644 index 0000000..697dd37 --- /dev/null +++ b/ObjectDetections/yolo2/model.py @@ -0,0 +1,89 @@ +""" +YOLOv2 implemented by Tensorflow, only for predicting +""" +import os + +import numpy as np +import tensorflow as tf + + + +######## basic layers ####### + +def leaky_relu(x): + return tf.nn.leaky_relu(x, alpha=0.1, name="leaky_relu") + +# Conv2d +def conv2d(x, filters, size, pad=0, stride=1, batch_normalize=1, + activation=leaky_relu, use_bias=False, name="conv2d"): + if pad > 0: + x = tf.pad(x, [[0, 0], [pad, pad], [pad, pad], [0, 0]]) + out = tf.layers.conv2d(x, filters, size, strides=stride, padding="VALID", + activation=None, use_bias=use_bias, name=name) + if batch_normalize == 1: + out = tf.layers.batch_normalization(out, axis=-1, momentum=0.9, + training=False, name=name+"_bn") + if activation: + out = activation(out) + return out + +# maxpool2d +def maxpool(x, size=2, stride=2, name="maxpool"): + return tf.layers.max_pooling2d(x, size, stride) + +# reorg layer +def reorg(x, stride): + return tf.extract_image_patches(x, [1, stride, stride, 1], + [1, stride, stride, 1], [1,1,1,1], padding="VALID") + + +def darknet(images, n_last_channels=425): + """Darknet19 for YOLOv2""" + net = conv2d(images, 32, 3, 1, name="conv1") + net = maxpool(net, name="pool1") + net = conv2d(net, 64, 3, 1, name="conv2") + net = maxpool(net, name="pool2") + net = conv2d(net, 128, 3, 1, name="conv3_1") + net = conv2d(net, 64, 1, name="conv3_2") + net = conv2d(net, 128, 3, 1, name="conv3_3") + net = maxpool(net, name="pool3") + net = conv2d(net, 256, 3, 1, name="conv4_1") + net = conv2d(net, 128, 1, name="conv4_2") + net = conv2d(net, 256, 3, 1, name="conv4_3") + net = maxpool(net, name="pool4") + net = conv2d(net, 512, 3, 1, name="conv5_1") + net = conv2d(net, 256, 1, name="conv5_2") + net = conv2d(net, 512, 3, 1, name="conv5_3") + net = conv2d(net, 256, 1, name="conv5_4") + net = conv2d(net, 512, 3, 1, name="conv5_5") + shortcut = net + net = maxpool(net, name="pool5") + net = conv2d(net, 1024, 3, 1, name="conv6_1") + net = conv2d(net, 512, 1, name="conv6_2") + net = conv2d(net, 1024, 3, 1, name="conv6_3") + net = conv2d(net, 512, 1, name="conv6_4") + net = conv2d(net, 1024, 3, 1, name="conv6_5") + # --------- + net = conv2d(net, 1024, 3, 1, name="conv7_1") + net = conv2d(net, 1024, 3, 1, name="conv7_2") + # shortcut + shortcut = conv2d(shortcut, 64, 1, name="conv_shortcut") + shortcut = reorg(shortcut, 2) + net = tf.concat([shortcut, net], axis=-1) + net = conv2d(net, 1024, 3, 1, name="conv8") + # detection layer + net = conv2d(net, n_last_channels, 1, batch_normalize=0, + activation=None, use_bias=True, name="conv_dec") + return net + + + +if __name__ == "__main__": + x = tf.random_normal([1, 416, 416, 3]) + model = darknet(x) + + saver = tf.train.Saver() + with tf.Session() as sess: + saver.restore(sess, "./checkpoint_dir/yolo2_coco.ckpt") + print(sess.run(model).shape) + diff --git a/ObjectDetections/yolo2/utils.py b/ObjectDetections/yolo2/utils.py new file mode 100644 index 0000000..5821a3b --- /dev/null +++ b/ObjectDetections/yolo2/utils.py @@ -0,0 +1,163 @@ +""" +Help functions for YOLOv2 +""" +import random +import colorsys + +import cv2 +import numpy as np + + + +############## preprocess image ################## + + +def preprocess_image(image, image_size=(416, 416)): + """Preprocess a image to inference""" + image_cp = np.copy(image).astype(np.float32) + # resize the image + image_rgb = cv2.cvtColor(image_cp, cv2.COLOR_BGR2RGB) + image_resized = cv2.resize(image_rgb, image_size) + # normalize + image_normalized = image_resized.astype(np.float32) / 255.0 + # expand the batch_size dim + image_expanded = np.expand_dims(image_normalized, axis=0) + return image_expanded + +def postprocess(bboxes, obj_probs, class_probs, image_shape=(416, 416), + threshold=0.5): + """post process the detection results""" + bboxes = np.reshape(bboxes, [-1, 4]) + bboxes[:, 0::2] *= float(image_shape[1]) + bboxes[:, 1::2] *= float(image_shape[0]) + bboxes = bboxes.astype(np.int32) + + # clip the bboxs + bbox_ref = [0, 0, image_shape[1] - 1, image_shape[0] - 1] + bboxes = bboxes_clip(bbox_ref, bboxes) + + obj_probs = np.reshape(obj_probs, [-1]) + class_probs = np.reshape(class_probs, [len(obj_probs), -1]) + class_inds = np.argmax(class_probs, axis=1) + class_probs = class_probs[np.arange(len(obj_probs)), class_inds] + scores = obj_probs * class_probs + + # filter bboxes with scores > threshold + keep_inds = scores > threshold + bboxes = bboxes[keep_inds] + scores = scores[keep_inds] + class_inds = class_inds[keep_inds] + + # sort top K + class_inds, scores, bboxes = bboxes_sort(class_inds, scores, bboxes) + # nms + class_inds, scores, bboxes = bboxes_nms(class_inds, scores, bboxes) + + return bboxes, scores, class_inds + +def draw_detection(im, bboxes, scores, cls_inds, labels, thr=0.3): + # for display + ############################ + # Generate colors for drawing bounding boxes. + hsv_tuples = [(x / float(len(labels)), 1., 1.) + for x in range(len(labels))] + colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples)) + colors = list( + map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)), + colors)) + random.seed(10101) # Fixed seed for consistent colors across runs. + random.shuffle(colors) # Shuffle colors to decorrelate adjacent classes. + random.seed(None) # Reset seed to default. + # draw image + imgcv = np.copy(im) + h, w, _ = imgcv.shape + for i, box in enumerate(bboxes): + if scores[i] < thr: + continue + cls_indx = cls_inds[i] + + thick = int((h + w) / 300) + cv2.rectangle(imgcv, + (box[0], box[1]), (box[2], box[3]), + colors[cls_indx], thick) + mess = '%s: %.3f' % (labels[cls_indx], scores[i]) + if box[1] < 20: + text_loc = (box[0] + 2, box[1] + 15) + else: + text_loc = (box[0], box[1] - 10) + cv2.putText(imgcv, mess, text_loc, + cv2.FONT_HERSHEY_SIMPLEX, 1e-3 * h, colors[cls_indx], thick // 3) + + return imgcv + + +############## process bboxes ################## +def bboxes_clip(bbox_ref, bboxes): + """Clip bounding boxes with respect to reference bbox. + """ + bboxes = np.copy(bboxes) + bboxes = np.transpose(bboxes) + bbox_ref = np.transpose(bbox_ref) + bboxes[0] = np.maximum(bboxes[0], bbox_ref[0]) + bboxes[1] = np.maximum(bboxes[1], bbox_ref[1]) + bboxes[2] = np.minimum(bboxes[2], bbox_ref[2]) + bboxes[3] = np.minimum(bboxes[3], bbox_ref[3]) + bboxes = np.transpose(bboxes) + return bboxes + +def bboxes_sort(classes, scores, bboxes, top_k=400): + """Sort bounding boxes by decreasing order and keep only the top_k + """ + # if priority_inside: + # inside = (bboxes[:, 0] > margin) & (bboxes[:, 1] > margin) & \ + # (bboxes[:, 2] < 1-margin) & (bboxes[:, 3] < 1-margin) + # idxes = np.argsort(-scores) + # inside = inside[idxes] + # idxes = np.concatenate([idxes[inside], idxes[~inside]]) + idxes = np.argsort(-scores) + classes = classes[idxes][:top_k] + scores = scores[idxes][:top_k] + bboxes = bboxes[idxes][:top_k] + return classes, scores, bboxes + +def bboxes_iou(bboxes1, bboxes2): + """Computing iou between bboxes1 and bboxes2. + Note: bboxes1 and bboxes2 can be multi-dimensional, but should broacastable. + """ + bboxes1 = np.transpose(bboxes1) + bboxes2 = np.transpose(bboxes2) + # Intersection bbox and volume. + int_ymin = np.maximum(bboxes1[0], bboxes2[0]) + int_xmin = np.maximum(bboxes1[1], bboxes2[1]) + int_ymax = np.minimum(bboxes1[2], bboxes2[2]) + int_xmax = np.minimum(bboxes1[3], bboxes2[3]) + + int_h = np.maximum(int_ymax - int_ymin, 0.) + int_w = np.maximum(int_xmax - int_xmin, 0.) + int_vol = int_h * int_w + # Union volume. + vol1 = (bboxes1[2] - bboxes1[0]) * (bboxes1[3] - bboxes1[1]) + vol2 = (bboxes2[2] - bboxes2[0]) * (bboxes2[3] - bboxes2[1]) + iou = int_vol / (vol1 + vol2 - int_vol) + return iou + +def bboxes_nms(classes, scores, bboxes, nms_threshold=0.5): + """Apply non-maximum selection to bounding boxes. + """ + keep_bboxes = np.ones(scores.shape, dtype=np.bool) + for i in range(scores.size-1): + if keep_bboxes[i]: + # Computer overlap with bboxes which are following. + overlap = bboxes_iou(bboxes[i], bboxes[(i+1):]) + # Overlap threshold for keeping + checking part of the same class + keep_overlap = np.logical_or(overlap < nms_threshold, classes[(i+1):] != classes[i]) + keep_bboxes[(i+1):] = np.logical_and(keep_bboxes[(i+1):], keep_overlap) + + idxes = np.where(keep_bboxes) + return classes[idxes], scores[idxes], bboxes[idxes] + + + + + + diff --git a/README.md b/README.md index c624ce7..b1ebefe 100644 --- a/README.md +++ b/README.md @@ -2,19 +2,33 @@ The deeplearning algorithms are carefully implemented by [tensorflow](https://www.tensorflow.org/). ### Environment - Python 3.5 -- tensorflow 0.12 +- tensorflow 1.4 +- pytorch 0.2.0 ### The deeplearning algorithms includes (now): - Logistic Regression [logisticRegression.py](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/models/logisticRegression.py) - Multi-Layer Perceptron (MLP) [mlp.py](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/models/mlp.py) - Convolution Neural Network (CNN) [cnn.py](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/models/cnn.py) - Denoising Aotoencoder (DA) [da.py](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/models/da.py) -- Stacked Denoising Autoencoder (SDA) [sda.py](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/models/sdan.py) +- Stacked Denoising Autoencoder (SDA) [sda.py](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/models/sda.py) - Restricted Boltzmann Machine (RBM) [[rbm.py](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/models/rbm.py) [gbrbm.py](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/models/gbrbm.py)] - Deep Belief Network (DBN) [dbn.py](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/models/dbn.py) Note: the project aims at imitating the well-implemented algorithms in [Deep Learning Tutorials](http://www.deeplearning.net/tutorial/) (coded by [Theano](http://deeplearning.net/software/theano/index.html)). +### CNN Models +- MobileNet [[self](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/CNNs/MobileNet.py) [paper](https://arxiv.org/abs/1704.04861) [ref](https://github.com/Zehaos/MobileNet/blob/master/nets/mobilenet.py)] +- MobileNetv2 [[self](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/CNNs/mobilenet_v2.py) [paper](https://arxiv.org/pdf/1801.04381.pdf) [ref](https://github.com/tensorflow/models/tree/master/research/slim/nets/mobilenet)] +- SqueezeNet [[self](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/CNNs/SqueezeNet.py) [paper](https://arxiv.org/abs/1602.07360)] +- ResNet [[self](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/CNNs/ResNet50.py) [caffe ref](https://github.com/KaimingHe/deep-residual-networks) [paper1](https://arxiv.org/abs/1512.03385) [paper2](https://arxiv.org/abs/1603.05027)] +- ShuffleNet [[self](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/CNNs/ShuffleNet.py) by pytorch [paper](http://cn.arxiv.org/pdf/1707.01083v2)] +- ShuffleNetv2 [[self](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/CNNs/shufflenet_v2.py) [ref](https://github.com/tensorpack/tensorpack/blob/master/examples/ImageNetModels/shufflenet.py) [paper](https://arxiv.org/abs/1807.11164)] +- DenseNet [[self](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/CNNs/densenet.py) [pytorch_ref](https://github.com/pytorch/vision/blob/master/torchvision/models/densenet.py) [paper](https://arxiv.org/abs/1608.06993)] + +### Object detection +- YOLOv1 [[self](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/ObjectDetections/yolo/yolo_tf.py) [paper](https://arxiv.org/abs/1506.02640) [ref](https://github.com/gliese581gg/YOLO_tensorflow)] +- SSD [[self](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/ObjectDetections/SSD/SSD_demo.py) [paper](https://arxiv.org/pdf/1611.10012.pdf) [slides](http://www.cs.unc.edu/~wliu/papers/ssd_eccv2016_slide.pdf) [cafe](https://github.com/weiliu89/caffe/tree/ssd) [TF](https://arxiv.org/abs/1512.02325) [pytorch](https://github.com/amdegroot/ssd.pytorch) ] +- YOLOv2 [[self](https://github.com/xiaohu2015/DeepLearning_tutorials/tree/master/ObjectDetections/yolo2) [paper](https://arxiv.org/abs/1612.08242) [ref](https://github.com/yhcc/yolo2)] ### Practical examples You can find more practical examples with tensorflow here: @@ -37,6 +51,23 @@ You can find more practical examples with tensorflow here: ### Fun Blogs - [Chatbots with Seq2Seq](http://suriyadeepan.github.io/2016-06-28-easy-seq2seq/) +### Personal Notes +- Tensorflow for RNNs [[tf_rnn.ipynb](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/notes/tf_rnn.ipynb)] +- Tensorflow for Autoencoder [[tf_autoencoder.ipynb](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/notes/tf_autoencoder.ipynb)] + +### Other Tutorials +- [ageron/handson-ml +](https://github.com/ageron/handson-ml/) +- [Hvass-Labs/TensorFlow-Tutorials +](https://github.com/Hvass-Labs/TensorFlow-Tutorials) +- [BinRoot/TensorFlow-Book +](https://github.com/BinRoot/TensorFlow-Book) +- [sjchoi86/dl_tutorials_10weeks +](https://github.com/sjchoi86/dl_tutorials_10weeks) + #### Don't hesitate to star this project if it is helpful! ### If you benefit from the tutorial, please make a small donation by WeChat sweep. ![weichat](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/results/weichat.jpg) +## 微信号:xiaoxiaohu1994 +## 欢迎关注微信公众号:机器学习算法全栈工程师(Jeemy110) +![公众号](https://github.com/xiaohu2015/DeepLearning_tutorials/blob/master/results/654362565405877642.jpg) diff --git a/examples/cnn_setence_classification/text_cnn.py b/examples/cnn_setence_classification/text_cnn.py index f186faf..3518a5c 100644 --- a/examples/cnn_setence_classification/text_cnn.py +++ b/examples/cnn_setence_classification/text_cnn.py @@ -81,7 +81,7 @@ def __init__(self, seq_len, vocab_size, embedding_size, filter_sizes, num_filter pooled_outputs.append(pool_output) # [None, 1, 1, num_filters] # Combine all pooled features num_filters_total = num_filters * len(filter_sizes) - self.h_pool = tf.concat(3, pooled_outputs) # [None, 1, 1, num_filters_total] + self.h_pool = tf.concat( pooled_outputs,3) # [None, 1, 1, num_filters_total] self.h_pool_flat = tf.reshape(self.h_pool, shape=[-1, num_filters_total]) # [None, num_filters_total] # The dropout layer @@ -100,7 +100,7 @@ def __init__(self, seq_len, vocab_size, embedding_size, filter_sizes, num_filter # The loss with tf.name_scope("loss"): - losses = tf.nn.softmax_cross_entropy_with_logits(self.scores, self.y) + losses = tf.nn.softmax_cross_entropy_with_logits(logits=self.scores, labels=self.y) self.loss = tf.reduce_mean(losses) + L2_loss * l2_reg_lambda # Accuracy diff --git a/examples/cnn_setence_classification/train_cnn.py b/examples/cnn_setence_classification/train_cnn.py index aefa2b5..bc58dc0 100644 --- a/examples/cnn_setence_classification/train_cnn.py +++ b/examples/cnn_setence_classification/train_cnn.py @@ -1,74 +1,74 @@ -""" -Test the TextRNN class -2016/12/22 -""" -import os -import sys -import numpy as np -import tensorflow as tf -from sklearn.model_selection import train_test_split -from tensorflow.contrib import learn - -from data_helpers import load_data_and_labels, batch_iter -from text_cnn import TextCNN - - -# Load original data -path = sys.path[0] -pos_filename = path + "/data/rt-polarity.pos" -neg_filename = path + "/data/rt-polarity.neg" - -X_data, y_data = load_data_and_labels(pos_filename, neg_filename) -max_document_length = max([len(sen.split(" ")) for sen in X_data]) -print("Max_document_length:,", max_document_length) -# Create the vacabulary -vocab_processor = learn.preprocessing.VocabularyProcessor(max_document_length) -# The idx data -x = np.array(list(vocab_processor.fit_transform(X_data)), dtype=np.float32) -y = np.array(y_data, dtype=np.int32) -vocabulary_size = len(vocab_processor.vocabulary_) -print("The size of vocabulary:", vocabulary_size) -# Split the data -X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.1, random_state=1111) -print("X_train shape {0}, y_train shape {1}".format(X_train.shape, y_train.shape)) -print("X_test shape {0}, y_test shape {1}".format(X_test.shape, y_test.shape)) - -# The parameters of RNN -seq_len = X_train.shape[1] -vocab_size = vocabulary_size -embedding_size = 128 -filter_sizes = [2, 3, 4] -num_filters = 128 -num_classes = y_train.shape[1] -l2_reg_lambda = 0.0 - -# Construct RNN model -text_rnn_model = TextCNN(seq_len=seq_len, vocab_size=vocab_size, embedding_size=embedding_size, filter_sizes= - filter_sizes, num_filters=num_filters, num_classes=num_classes) -loss = text_rnn_model.loss -train_op = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss) -accuracy = text_rnn_model.accuracy -# The parameters for training -batch_size = 64 -training_epochs = 10 -dispaly_every = 1 -dropout_keep_prob = 0.5 - -batch_num = int(X_train.shape[0]/batch_size) - -sess = tf.Session() -sess.run(tf.global_variables_initializer()) -print("Starting training...") -for epoch in range(training_epochs): - avg_cost = 0 - for batch in range(batch_num): - _, cost = sess.run([train_op, loss], feed_dict={text_rnn_model.x: X_train[batch*batch_size:(batch+1)*batch_size], - text_rnn_model.y: y_train[batch*batch_size:(batch+1)*batch_size], - text_rnn_model.dropout_keep_prob:dropout_keep_prob}) - avg_cost += cost - if epoch % dispaly_every == 0: - cost, acc = sess.run([loss, accuracy], feed_dict={text_rnn_model.x: X_test, - text_rnn_model.y: y_test, - text_rnn_model.dropout_keep_prob: 1.0}) - print("\nEpoch {0} : loss {1}, accuracy {2}".format(epoch, cost, acc)) - +""" +Test the TextRNN class +2016/12/22 +""" +import os +import sys +import numpy as np +import tensorflow as tf +from sklearn.model_selection import train_test_split +from tensorflow.contrib import learn + +from data_helpers import load_data_and_labels, batch_iter +from text_cnn import TextCNN +import pudb;pu.db + +# Load original data +path = sys.path[0] +pos_filename = path + "/data/rt-polarity.pos" +neg_filename = path + "/data/rt-polarity.neg" + +X_data, y_data = load_data_and_labels(pos_filename, neg_filename) +max_document_length = max([len(sen.split(" ")) for sen in X_data]) +print("Max_document_length:,", max_document_length) +# Create the vacabulary +vocab_processor = learn.preprocessing.VocabularyProcessor(max_document_length) +# The idx data +x = np.array(list(vocab_processor.fit_transform(X_data)), dtype=np.float32) +y = np.array(y_data, dtype=np.int32) +vocabulary_size = len(vocab_processor.vocabulary_) +print("The size of vocabulary:", vocabulary_size) +# Split the data +X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.1, random_state=1111) +print("X_train shape {0}, y_train shape {1}".format(X_train.shape, y_train.shape)) +print("X_test shape {0}, y_test shape {1}".format(X_test.shape, y_test.shape)) + +# The parameters of RNN +seq_len = X_train.shape[1] +vocab_size = vocabulary_size +embedding_size = 128 +filter_sizes = [2, 3, 4] +num_filters = 128 +num_classes = y_train.shape[1] +l2_reg_lambda = 0.0 + +# Construct RNN model +text_rnn_model = TextCNN(seq_len=seq_len, vocab_size=vocab_size, embedding_size=embedding_size, filter_sizes= + filter_sizes, num_filters=num_filters, num_classes=num_classes) +loss = text_rnn_model.loss +train_op = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss) +accuracy = text_rnn_model.accuracy +# The parameters for training +batch_size = 64 +training_epochs = 10 +dispaly_every = 1 +dropout_keep_prob = 0.5 + +batch_num = int(X_train.shape[0]/batch_size) + +sess = tf.Session() +sess.run(tf.global_variables_initializer()) +print("Starting training...") +for epoch in range(training_epochs): + avg_cost = 0 + for batch in range(batch_num): + _, cost = sess.run([train_op, loss], feed_dict={text_rnn_model.x: X_train[batch*batch_size:(batch+1)*batch_size], + text_rnn_model.y: y_train[batch*batch_size:(batch+1)*batch_size], + text_rnn_model.dropout_keep_prob:dropout_keep_prob}) + avg_cost += cost + if epoch % dispaly_every == 0: + cost, acc = sess.run([loss, accuracy], feed_dict={text_rnn_model.x: X_test, + text_rnn_model.y: y_test, + text_rnn_model.dropout_keep_prob: 1.0}) + print("\nEpoch {0} : loss {1}, accuracy {2}".format(epoch, cost, acc)) + diff --git a/notes/tf_autoencoder.ipynb b/notes/tf_autoencoder.ipynb new file mode 100644 index 0000000..04164d6 --- /dev/null +++ b/notes/tf_autoencoder.ipynb @@ -0,0 +1,1809 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "deletable": true, + "editable": true + }, + "source": [ + "# Tensorflow for autoencoder" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true, + "deletable": true, + "editable": true + }, + "outputs": [], + "source": [ + "# load library\n", + "import os\n", + "import sys\n", + "\n", + "import numpy as np\n", + "np.random.seed(42)\n", + "\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline\n", + "plt.rcParams[\"axes.labelsize\"] = 14\n", + "plt.rcParams[\"xtick.labelsize\"] = 12\n", + "plt.rcParams[\"ytick.labelsize\"] = 12\n", + "\n", + "import tensorflow as tf\n", + "\n", + "PROJECT_ROOT_DIR = \".\"\n", + "ID = \"autoencoders\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, + "outputs": [], + "source": [ + "# utility functions\n", + "# save figures\n", + "def save_fig(fig_id, tight_layout=True):\n", + " path = os.path.join(PROJECT_ROOT_DIR, \"images\", ID, fig_id + \".png\")\n", + " print(\"Saving figure\", fig_id)\n", + " if tight_layout:\n", + " plt.tight_layout()\n", + " plt.savefig(path, format=\"png\", dpi=300)\n", + "\n", + "def plot_image(image, shape=[28, 28]):\n", + " plt.imshow(image.reshape(shape), cmap=\"Greys\", interpolation=\"nearest\")\n", + " plt.axis(\"off\")\n", + " \n", + "def plot_multi_images(images, n_rows, n_cols, pad=2):\n", + " images -= images.min()\n", + " w, h = images.shape[1:]\n", + " image = np.zeros(((w + pad) * n_rows + pad, (h + pad) * n_cols + pad))\n", + " for y in range(n_rows):\n", + " for x in range(n_cols):\n", + " image[(y*(w+pad)+pad):(y*(w+pad)+pad+h), (x*(h+pad)+pad):(x*(h+pad)+pad+h)] = images[y*n_cols+x]\n", + " plt.imshow(image, cmap=\"Greys\", interpolation=\"nearest\")\n", + " plt.axis(\"off\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": true, + "editable": true + }, + "source": [ + "## PCA with a linear Autoencoder" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, + "outputs": [], + "source": [ + "# 3D dataset\n", + "np.random.seed(2017)\n", + "m = 100\n", + "w1, w2 = 0.1, 0.3\n", + "noise = 0.1\n", + "\n", + "angles = np.random.rand(m) * 3 * np.pi / 2 - 0.5\n", + "X_train = np.empty((m, 3))\n", + "X_train[:, 0] = np.cos(angles) + np.sin(angles)/2 + noise * np.random.randn(m) / 2\n", + "X_train[:, 1] = np.sin(angles) * 0.7 + noise * np.random.randn(m) / 2\n", + "X_train[:, 2] = X_train[:, 0] * w1 + X_train[:, 1] * w2 + noise * np.random.randn(m)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": true, + "deletable": true, + "editable": true + }, + "outputs": [], + "source": [ + "# normalize the data\n", + "from sklearn.preprocessing import StandardScaler\n", + "scaler = StandardScaler()\n", + "X_train = scaler.fit_transform(X_train)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": true, + "deletable": true, + "editable": true + }, + "outputs": [], + "source": [ + "# PCA\n", + "tf.reset_default_graph()\n", + "\n", + "n_inputs = 3\n", + "n_hidden = 2 # encoder\n", + "n_outputs = n_inputs\n", + "\n", + "learning_rate = 0.01\n", + "\n", + "X = tf.placeholder(tf.float32, [None, n_inputs])\n", + "h = tf.layers.dense(X, n_hidden, activation=None) # linear transform\n", + "outputs = tf.layers.dense(h, n_outputs, activation=None)\n", + "\n", + "mse_loss = tf.reduce_mean(tf.square(X - outputs))\n", + "\n", + "train_op = tf.train.AdamOptimizer(learning_rate).minimize(mse_loss)\n", + "init = tf.global_variables_initializer()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 0 mse: 1.77635\n", + "Epoch 1000 mse: 0.0443353\n", + "Epoch 2000 mse: 0.043948\n", + "Epoch 3000 mse: 0.0439479\n", + "Epoch 4000 mse: 0.0439479\n", + "Epoch 5000 mse: 0.0439501\n", + "Epoch 6000 mse: 0.043948\n", + "Epoch 7000 mse: 0.043948\n", + "Epoch 8000 mse: 0.043948\n", + "Epoch 9000 mse: 0.0439479\n" + ] + } + ], + "source": [ + "n_epochs = 10000\n", + "\n", + "with tf.Session() as sess:\n", + " sess.run(init)\n", + " for epoch in range(n_epochs):\n", + " _, mse = sess.run([train_op, mse_loss], feed_dict={X: X_train})\n", + " if epoch % 1000 == 0:\n", + " print(\"Epoch\", epoch, \"mse:\", mse)\n", + " encoded_output = sess.run(h, feed_dict={X: X_train})" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saving figure linear_autoencoder_pca_plot\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# plot\n", + "fig = plt.figure(figsize=(4,3))\n", + "plt.plot(encoded_output[:,0], encoded_output[:, 1], \"b.\")\n", + "plt.xlabel(\"$z_1$\", fontsize=18)\n", + "plt.ylabel(\"$z_2$\", fontsize=18, rotation=0)\n", + "save_fig(\"linear_autoencoder_pca_plot\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": true, + "editable": true + }, + "source": [ + "## Stacked Autoencoders" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Extracting /tmp/data/train-images-idx3-ubyte.gz\n", + "Extracting /tmp/data/train-labels-idx1-ubyte.gz\n", + "Extracting /tmp/data/t10k-images-idx3-ubyte.gz\n", + "Extracting /tmp/data/t10k-labels-idx1-ubyte.gz\n" + ] + } + ], + "source": [ + "# mnist dataset\n", + "from tensorflow.examples.tutorials.mnist import input_data\n", + "mnist = input_data.read_data_sets(\"/tmp/data/\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": true, + "editable": true + }, + "source": [ + "### Train all layers at once" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": true, + "deletable": true, + "editable": true + }, + "outputs": [], + "source": [ + "tf.reset_default_graph()\n", + "\n", + "from functools import partial\n", + "\n", + "n_inputs = 28*28\n", + "n_hidden1 = 300\n", + "n_hidden2 = 150 # encoding\n", + "n_hidden3 = n_hidden1\n", + "n_outputs = n_inputs\n", + "\n", + "learning_rate = 0.01\n", + "l2_reg = 1e-4\n", + "\n", + "dense_layer = partial(tf.layers.dense, activation=tf.nn.elu, \n", + " kernel_initializer=tf.contrib.layers.variance_scaling_initializer(),\n", + " kernel_regularizer=tf.contrib.layers.l2_regularizer(l2_reg))\n", + "\n", + "X = tf.placeholder(tf.float32, [None, n_inputs])\n", + "\n", + "h1 = dense_layer(X, n_hidden1)\n", + "h2 = dense_layer(h1, n_hidden2)\n", + "h3 = dense_layer(h2, n_hidden3)\n", + "outputs = dense_layer(h3, n_outputs, activation=None)\n", + "\n", + "mse_loss = tf.reduce_mean(tf.square(outputs - X))\n", + "reg_loss = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)\n", + "loss = tf.add_n([mse_loss] + reg_loss)\n", + "\n", + "train_op = tf.train.AdamOptimizer(learning_rate).minimize(loss)\n", + "init = tf.global_variables_initializer()\n", + "saver = tf.train.Saver()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 0 mse: 0.0240489\n", + "Epoch 1 mse: 0.0128124\n", + "Epoch 2 mse: 0.0118014\n", + "Epoch 3 mse: 0.0113695\n", + "Epoch 4 mse: 0.0111495\n" + ] + } + ], + "source": [ + "n_epochs = 5\n", + "batch_size = 128\n", + "num_batch = mnist.train.num_examples // batch_size\n", + "\n", + "with tf.Session() as sess:\n", + " sess.run(init)\n", + " for epoch in range(n_epochs):\n", + " for t in range(num_batch):\n", + " X_batch, _ = mnist.train.next_batch(batch_size)\n", + " _, mse_train = sess.run([train_op, mse_loss], feed_dict={X: X_batch})\n", + " print(\"Epoch\", epoch, \"mse:\", mse_train)\n", + " saver.save(sess, \"./tmp/my_model_all_layers.ckpt\")" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": true, + "deletable": true, + "editable": true + }, + "outputs": [], + "source": [ + "def show_reconstructed_digits(X, outputs, model_path = None, n_test_digits = 2):\n", + " with tf.Session() as sess:\n", + " if model_path:\n", + " saver.restore(sess, model_path)\n", + " X_test = mnist.test.images[:n_test_digits]\n", + " outputs_val = outputs.eval(feed_dict={X: X_test})\n", + "\n", + " fig = plt.figure(figsize=(8, 3 * n_test_digits))\n", + " for digit_index in range(n_test_digits):\n", + " plt.subplot(n_test_digits, 2, digit_index * 2 + 1)\n", + " plot_image(X_test[digit_index])\n", + " plt.subplot(n_test_digits, 2, digit_index * 2 + 2)\n", + " plot_image(outputs_val[digit_index])" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "INFO:tensorflow:Restoring parameters from ./tmp/my_model_all_layers.ckpt\n", + "Saving figure reconstruction_plot\n" + ] + }, + { + "data": { + "image/png": "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\n/e9/h9d+8IMfdBpr1apV4bXf/va31frcuXOr9WhT+KhrsJRSnn/++Wr9kUceqda3bdsWjgWHirGx\nsfDa3r17q/Vdu3ZV661O4+3bt1frRx55ZLW+evXqcKz3ve991fpFF11UrS9atKhajzq8Synl9ttv\nr9affvrpaj06dKKU+HcpOpBh3759nceKOs8nssv6YPKEDAAJCGQASEAgA0ACAhkAEhDIAJCALusD\n0Oo0jrr6om7q3//+9+FYUadlV3feeWd47R//+Eensa666qpx3g3k19qfOLoWdeHOmzcvHOud73xn\ntb5w4cJqPdrHvpRSPvjBD3Yaa+fOndV6tC91KfHe29FY0cqPUuLVItHnG3W3l1LKnDlzwmtdx4q+\nx6j7u9WRP16ekAEgAYEMAAkIZABIQCADQAICGQASEMgAkIBlTwfgPe95T3gtWhIVtf93bdfvRevA\ni1b7PxzqZs2q/+RFyxdLiZflDA4OVut9fX3hWEuXLq3WoyU2J554YjhW9JroAIvHHnusWr///vvD\nObZs2VKtv/vd767Wly1bFo4V/SZG72NkZCQcKxItrWr97kWHWHRdDjURPCEDQAICGQASEMgAkIBA\nBoAEBDIAJKDLepyijdwnw1133VWtP/HEE53HuuKKK6r1U045pfNYMNWiTtioczaqt0Rdw63fhKGh\noWo96sweGBgIx4q6qaPO6Ohgm6effjqcY/HixdX6pZdeWq2fffbZ4VhRJ/vu3bur9V27doVj9ff3\nV+t79uyp1lud0dF3v3///s5jjZcnZABIQCADQAICGQASEMgAkIBABoAEdFlPA//85z+r9c9+9rPV\nemsP2CVLllTrt9xyS7Xe2pcXppuJ7LKOOn1bf39RZ3ZUb+2x3XUv6w0bNlTr0V7dpZRy4YUXVutR\nN3WrwzzaMzraZ7r1nURnAoyOjnaau5T4M57Ifc8PlCdkAEhAIANAAgIZABIQyACQgEAGgAQEMgAk\nYNnTNLBmzZpqvbW8InLDDTdU66eddlrnsSCraGnK2NhYtR4tcSklXsoSzdH6uxweHq7W582bV61H\nhyWUUsrLL79crf/ud7+r1h999NFqfenSpeEc5557brW+atWqaj1avlVKfIjE3Llzq/VoaVMp8XcS\nfb+9LFWKXtPLErkD5QkZABIQyACQgEAGgAQEMgAkIJABIAFd1olcd9111fo999zTaZwvfelL4bWv\n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\nJPA/Qsg5S0GmIi4AAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show_reconstructed_digits(X, outputs, \"./tmp/my_model_all_layers.ckpt\")\n", + "save_fig(\"reconstruction_plot\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": true, + "editable": true + }, + "source": [ + "### Tying weigts" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": true, + "deletable": true, + "editable": true + }, + "outputs": [], + "source": [ + "tf.reset_default_graph()\n", + "\n", + "activation = tf.nn.elu\n", + "regularizer = tf.contrib.layers.l2_regularizer(l2_reg)\n", + "initializer = tf.contrib.layers.variance_scaling_initializer()\n", + "\n", + "X = tf.placeholder(tf.float32, [None, n_inputs])\n", + "\n", + "W1 = tf.Variable(initializer([n_inputs, n_hidden1]), dtype=tf.float32, name=\"W1\")\n", + "b1 = tf.Variable(tf.zeros([n_hidden1,]), name=\"b1\")\n", + "W2 = tf.Variable(initializer([n_hidden1, n_hidden2]), dtype=tf.float32, name=\"W2\")\n", + "b2 = tf.Variable(tf.zeros([n_hidden2,]), name=\"b2\")\n", + "W3 = tf.transpose(W2, name=\"W3\")\n", + "b3 = tf.Variable(tf.zeros([n_hidden3,]), name=\"b3\")\n", + "W4 = tf.transpose(W1, name=\"W4\")\n", + "b4 = tf.Variable(tf.zeros([n_outputs,]), name=\"b4\")\n", + "\n", + "h1 = activation(tf.nn.xw_plus_b(X, W1, b1))\n", + "h2 = activation(tf.nn.xw_plus_b(h1, W2, b2))\n", + "h3 = activation(tf.nn.xw_plus_b(h2, W3, b3))\n", + "outputs = tf.nn.xw_plus_b(h3, W4, b4)\n", + "\n", + "mse_loss = tf.reduce_mean(tf.square(outputs - X))\n", + "reg_loss = regularizer(W1) + regularizer(W2)\n", + "loss = mse_loss + reg_loss\n", + "\n", + "train_op = tf.train.AdamOptimizer(learning_rate).minimize(loss)\n", + "init = tf.global_variables_initializer()\n", + "saver = tf.train.Saver()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 0 mse: 0.0112707\n", + "Epoch 1 mse: 0.00796578\n", + "Epoch 2 mse: 0.00771752\n", + "Epoch 3 mse: 0.00727718\n", + "Epoch 4 mse: 0.00726337\n" + ] + } + ], + "source": [ + "n_epochs = 5\n", + "batch_size = 128\n", + "num_batch = mnist.train.num_examples // batch_size\n", + "\n", + "with tf.Session() as sess:\n", + " sess.run(init)\n", + " for epoch in range(n_epochs):\n", + " for t in range(num_batch):\n", + " X_batch, _ = mnist.train.next_batch(batch_size)\n", + " _, mse_train = sess.run([train_op, mse_loss], feed_dict={X: X_batch})\n", + " print(\"Epoch\", epoch, \"mse:\", mse_train)\n", + " saver.save(sess, \"./tmp/my_model_all_layers_tying.ckpt\")" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "INFO:tensorflow:Restoring parameters from ./tmp/my_model_all_layers_tying.ckpt\n", + "Saving figure reconstruction_plot2\n" + ] + }, + { + "data": { + "image/png": "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\nK3KgndQtnpABIAGBDAAJCGQASEAgA0ACAhkAEtBlTSmllL/97W/V+o033th5rMcee6xaj/afhakS\ndcjOnh0/m0T7TPcyVn9/f7UedWy3xor2so7eE80RjdMa65VXXqnWo/2qS4k7oy+44IJq/eijjw7H\niu59a1/uSC+d9weLJ2QASEAgA0ACAhkAEhDIAJCAQAaABAQyACRg2ROllFJ+/etfV+vRUolSSrn6\n6qur9fe85z2Tck3Qq2gpSy8HA0T/B+bOrf98RkubWtcVLS9qLeOJPsvo6GinuQcGBsI5RkZGqvUn\nnniiWt+yZUs41sUXX1ytn3POOZ2vK/qM0X1sHdKRiSdkAEhAIANAAgIZABIQyACQgEAGgAR0WR9m\noo7RNWvWVOutjtFvfetb1fqcOXO6XxhMgajTuNXNHHXuRvXoMIpS4s7srgdYtOaPOpAHBwc7zxEd\nIvHss89W68cff3w41kc/+tFqfenSpeF7uop+e+bNmxe+Z2xsrNMcrQM/DpQnZABIQCADQAICGQAS\nEMgAkIBABoAEdFkfZn70ox9V64888ki1/qlPfSocy57VHCpancZRZ3TUmT08PByOFXU6R93ffX19\n4VjRPNH1RntD79y5M5zjN7/5TbW+fv36an316tXhWFEHdrTyI9pHu5T4s0T3sTVW9N1H9/Fg8oQM\nAAkIZABIQCADQAICGQASEMgAkIBABoAELHs6BEUbv5dSyhe+8IVqfeHChdX6N7/5zUm5Jshg3759\n1XrrcImuh6VES29a80eHuPRyXdFBCtHyorVr14ZzRK8dffTR1fqll14ajrV48eJO19USLUmK7n1r\nWVsmnpABIAGBDAAJCGQASEAgA0ACAhkAEtBlPYNFG6Z/8pOfDN8TdW1ec8011boDJDiUzJ5dfwbp\npTM66vQdGhoKx4q6faPranUHR93UUf2ll16q1tesWRPOsXHjxmr9yiuvrNZXrVoVjhXd4+g3Keo8\nLyXuMI/Gan2/0Xuie98aK/oe95cnZABIQCADQAICGQASEMgAkIBABoAEdFnPAFGX52WXXVatP//8\n8+FYURfkN77xje4XBkl13dO41R3bdS/rVmd01Jk9MTFRrbc6eqPr2rp1a7V+5513Vuv3339/OMe5\n555brX/4wx+u1hcsWBCOFX2WqB7dq1JKGRsbq9anYs/qA+2kbo590EYGAPabQAaABAQyACQgkAEg\n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\nuygAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show_reconstructed_digits(X, outputs, \"./tmp/my_model_all_layers_tying.ckpt\")\n", + "save_fig(\"reconstruction_plot2\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": true, + "editable": true + }, + "source": [ + "### Training one Autoencoder at a time in multiple graphs" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, + "outputs": [], + "source": [ + "# a graph for a layer\n", + "def train_autoencoder_layer(inpt, n_units, n_epochs, batch_size, learning_rate = 0.01, \n", + " l2_reg = 0.0005, activation=tf.nn.elu, initializer=tf.contrib.layers.variance_scaling_initializer()):\n", + " graph = tf.Graph()\n", + " with graph.as_default():\n", + " n_inputs = inpt.shape[1]\n", + " regularizer = tf.contrib.layers.l2_regularizer(l2_reg)\n", + " X = tf.placeholder(tf.float32, [None, n_inputs])\n", + " \n", + " h = tf.layers.dense(X, n_units, activation=activation, name=\"hidden\", kernel_initializer=initializer,\n", + " kernel_regularizer=regularizer)\n", + " outputs = tf.layers.dense(h, n_inputs, activation=None, name=\"outputs\", kernel_initializer=initializer,\n", + " kernel_regularizer=regularizer)\n", + " \n", + " mse_loss = tf.reduce_mean(tf.square(outputs - X))\n", + " reg_loss = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)\n", + " loss = tf.add_n([mse_loss] + reg_loss)\n", + " \n", + " train_op = tf.train.AdamOptimizer(learning_rate).minimize(loss)\n", + " init = tf.global_variables_initializer()\n", + " \n", + " with tf.Session(graph=graph) as sess:\n", + " num_batch = len(inpt) // batch_size\n", + " sess.run(init)\n", + " for epoch in range(n_epochs):\n", + " for t in range(num_batch):\n", + " indices = np.random.permutation(len(inpt))[:batch_size]\n", + " X_batch = inpt[indices]\n", + " _, mse_train = sess.run([train_op, mse_loss], feed_dict={X: X_batch})\n", + " print(\"Epoch\", epoch, \"mse:\", mse_train)\n", + " params = dict([(var.name, var.eval()) for var in tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES)])\n", + " h_val = h.eval(feed_dict={X: inpt})\n", + " return h_val, params[\"hidden/kernel:0\"], params[\"hidden/bias:0\"], params[\"outputs/kernel:0\"], params[\"outputs/bias:0\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 0 mse: 0.0189829\n", + "Epoch 1 mse: 0.0184789\n", + "Epoch 2 mse: 0.0191758\n", + "Epoch 3 mse: 0.0191016\n", + "Epoch 0 mse: 0.00448945\n", + "Epoch 1 mse: 0.00456623\n", + "Epoch 2 mse: 0.00490648\n", + "Epoch 3 mse: 0.00482273\n" + ] + } + ], + "source": [ + "hidden_output, W1, b1, W4, b4 = train_autoencoder_layer(mnist.train.images, n_units=300, n_epochs=4, batch_size=150)\n", + "_, W2, b2, W3, b3 = train_autoencoder_layer(hidden_output, n_units=150, n_epochs=4, batch_size=150)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, + "outputs": [], + "source": [ + "# stack \n", + "tf.reset_default_graph()\n", + "\n", + "n_inputs = 28*28\n", + "\n", + "X = tf.placeholder(tf.float32, shape=[None, n_inputs])\n", + "hidden1 = tf.nn.elu(tf.matmul(X, W1) + b1)\n", + "hidden2 = tf.nn.elu(tf.matmul(hidden1, W2) + b2)\n", + "hidden3 = tf.nn.elu(tf.matmul(hidden2, W3) + b3)\n", + "outputs = tf.matmul(hidden3, W4) + b4" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, + "outputs": [ + { + "data": { + "image/png": "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\nAXXGDiUZmwcmAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show_reconstructed_digits(X, outputs)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "deletable": true, + "editable": true + }, + "source": [ + "### Training one Autoencoder at a time in a single graph (Tying Weights)" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, + "outputs": [], + "source": [ + "tf.reset_default_graph()\n", + "\n", + "n_inputs = 28*28\n", + "n_hidden1 = 300\n", + "n_hidden2 = 150 # encoding\n", + "n_hidden3 = n_hidden1\n", + "n_outputs = n_inputs\n", + "\n", + "learning_rate = 0.001\n", + "l2_reg = 1e-5\n", + "\n", + "activation = tf.nn.elu\n", + "regularizer = tf.contrib.layers.l2_regularizer(l2_reg)\n", + "initializer = tf.contrib.layers.variance_scaling_initializer()\n", + "\n", + "X = tf.placeholder(tf.float32, [None, n_inputs])\n", + "\n", + "W1 = tf.Variable(initializer([n_inputs, n_hidden1]), dtype=tf.float32, name=\"W1\")\n", + "b1 = tf.Variable(tf.zeros([n_hidden1,]), name=\"b1\")\n", + "W2 = tf.Variable(initializer([n_hidden1, n_hidden2]), dtype=tf.float32, name=\"W2\")\n", + "b2 = tf.Variable(tf.zeros([n_hidden2,]), name=\"b2\")\n", + "W3 = tf.transpose(W2, name=\"W3\")\n", + "b3 = tf.Variable(tf.zeros([n_hidden3,]), name=\"b3\")\n", + "W4 = tf.transpose(W1, name=\"W4\")\n", + "b4 = tf.Variable(tf.zeros([n_outputs,]), name=\"b4\")\n", + "\n", + "h1 = activation(tf.nn.xw_plus_b(X, W1, b1))\n", + "h2 = activation(tf.nn.xw_plus_b(h1, W2, b2))\n", + "h3 = activation(tf.nn.xw_plus_b(h2, W3, b3))\n", + "outputs = tf.nn.xw_plus_b(h3, W4, b4)\n", + "\n", + "with tf.name_scope(\"layer1\"):\n", + " layer1_outputs = tf.nn.xw_plus_b(h1, W4, b4)\n", + " layer1_mse = tf.reduce_mean(tf.square(layer1_outputs - X))\n", + " layer1_loss = layer1_mse + regularizer(W1)\n", + " layer1_train_op = tf.train.AdamOptimizer(learning_rate).minimize(layer1_loss, var_list=[W1, b1, b4])\n", + "\n", + "with tf.name_scope(\"layer2\"):\n", + " layer2_mse = tf.reduce_mean(tf.square(h3 - h1))\n", + " layer2_loss = layer2_mse + regularizer(W2)\n", + " layer2_train_op = tf.train.AdamOptimizer(learning_rate).minimize(layer2_loss, var_list=[W2, b2, b3])\n", + " \n", + "init = tf.global_variables_initializer()\n", + "saver = tf.train.Saver()" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training layer #1\n", + "0 Train MSE: 0.00377009\n", + "1 Train MSE: 0.00223285\n", + "2 Train MSE: 0.00165447\n", + "3 Train MSE: 0.00153537\n", + "49% Train MSE: 0.00142765\n", + "Training layer #2\n", + "0 Train MSE: 0.0172365\n", + "19% Train MSE: 0.00936307\n", + "2 Train MSE: 0.00732472\n", + "3 Train MSE: 0.00654762\n", + "49% Train MSE: 0.00575416\n", + "Test MSE: 0.00601665\n" + ] + } + ], + "source": [ + "training_ops = [layer1_train_op, layer2_train_op]\n", + "mses = [layer1_mse, layer2_mse]\n", + "n_epochs = [5, 5]\n", + "batch_sizes = [150, 150]\n", + "\n", + "with tf.Session() as sess:\n", + " init.run()\n", + " for layer in range(2):\n", + " print(\"Training layer #{}\".format(layer + 1))\n", + " if layer == 1:\n", + " mnist_hidden1 = h1.eval(feed_dict={X: mnist.train.images})\n", + " for epoch in range(n_epochs[layer]):\n", + " n_batches = mnist.train.num_examples // batch_sizes[layer]\n", + " for iteration in range(n_batches):\n", + " print(\"\\r{}%\".format(100 * iteration // n_batches), end=\"\")\n", + " sys.stdout.flush()\n", + " if layer == 1:\n", + " indices = np.random.permutation(len(mnist_hidden1))\n", + " hidden1_batch = mnist_hidden1[indices[:batch_sizes[layer]]]\n", + " feed_dict = {h1: hidden1_batch}\n", + " sess.run(training_ops[layer], feed_dict=feed_dict)\n", + " else:\n", + " X_batch, _ = mnist.train.next_batch(batch_sizes[layer])\n", + " feed_dict = {X: X_batch}\n", + " sess.run(training_ops[layer], feed_dict=feed_dict)\n", + " mse_train = mses[layer].eval(feed_dict=feed_dict)\n", + " print(\"\\r{}\".format(epoch), \"Train MSE:\", mse_train)\n", + " saver.save(sess, \"./my_model_cache_frozen.ckpt\")\n", + " mse_test = mses[layer].eval(feed_dict={X: mnist.test.images})\n", + " print(\"Test MSE:\", mse_test)" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "collapsed": false, + "deletable": true, + "editable": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "INFO:tensorflow:Restoring parameters from ./my_model_cache_frozen.ckpt\n" + ] + }, + { + "data": { + "image/png": "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\n8wIAuEPzAgC4Q2CjAr788ktTu+GGG0wt9tC4sbHR1BYuXGhqsQe0QE+LBS5UPcsDe/VaFSSIhQPU\n5InOzk5TiwW11Pm3bdtmaitXrjQ19b0PIYQrr7zS1M4991xTGzZsmFyfOvVDvc8Q0kM0ampI7Fyp\ntVJw5wUAcIfmBQBwh+YFAHCH5gUAcIfmBQBwh7RhBXz88cemFksWKmpPoiOOOKKkawLKKUuyTKXd\nYvt2qcRblmSdovbii53/jz/+MLXly5eb2ksvvWRqTU1N8phnnHGGqan9yOrr6+V6lbZUvyexPdLU\n+4+lNVOpv0mWkV8puPMCALhD8wIAuEPzAgC4Q/MCALhDYKOHXXvttab2/PPPJ6297bbbZP32228v\n6ZqAviTLKCEVpFDhgmKxKNfncjlTU/uB/fbbb3L9smXLTG3JkiWmVigUTG3mzJnymJMmTTK1UaNG\nJR0zBB3EUCGMWIhF1VM/51g9Fs4oJ+68AADu0LwAAO7QvAAA7tC8AADuVPXGgzWhIiftSW1tbbJ+\n+OGHm9rWrVtNTf2P+q+//loec8SIERmvbkAo72ZBSFYsFkv6PmcJbKhwwuDBNnfW3t4u16sgg/oN\n/Oijj+T65557ztTWrl1rameddZapXX/99fKY6ruvrikWuFD79qnPL7a/X5bpPkrqNI0sEzZyuVyX\n32fuvAAA7tC8AADu0LwAAO7QvAAA7jBho0wuvvhiWVfhDOXWW281NYIZGKhigQ0VWlCvrampST6u\nCne89957cv2bb75pauPGjTM1NTVDBUtCSA83xNarz0SFMIYOHSrXqy1V1NYzajpJCHoaR5YtabqL\nOy8AgDs0LwCAOzQvAIA7NC8AgDs0LwCAO6QNu+GLL74wtVg6SbnoootMbf78+aVcEtCvqDFQsbpK\nxsXShjt37jS1b775xtTWrVsn16u9v6ZNm2Zq06dPNzU1BioEff0qrRdL+5W6H5dKW6q0o3rv/3bc\nf4olSLuLOy8AgDs0LwCAOzQvAIA7NC8AgDsENrqwe/duU7vzzjtNraOjI/mYU6ZMMbXYA2ZgIIrt\n/aTqKpwQW//bb7+Z2vLly01t1apVcv3JJ59saueff76pHXzwwXK9UiwWTU3tvRXbd0sFJtQoKRVW\nib1W/R6pzzmE9JFd5d47kjsvAIA7NC8AgDs0LwCAOzQvAIA7BDa68Mgjj5jau+++m7z+2muvNTWm\naQD/LjaNQQUZFBW0CiGE9evXm9rnn39uarFpEmqaRlNTk6mpcEOhUJDHVO9J1dQkjti51CSS2H5g\ntbW1SceMfabqXKl/p1Jw5wUAcIfmBQBwh+YFAHCH5gUAcIfmBQBwp6rcIzsSVeSk3aGSOFlGQf35\n55+mVl9fX9I1QSrvZkFIViwWk7/P6vdGjTeK/S6pZNu+fftMbevWrXL9okWLTO311183tZkzZ8r1\nKik8duxYU0t9n7F6bBSTos6lPpNYglOlENUYrc2bN8v1+Xze1MaMGZN0nth15XK5Lr/P3HkBANyh\neQEA3KF5AQDcoXkBANxhPFQPa2trM7XYg9tSqHE2sYe+6mFubK8gRY2JWbhwYfJ6RV3rXXfdJV/b\nG6NnUJosQbAsez+pwIb6txMbpbRx40ZT27RpU9I1haD3xFLnUvthxY65a9cuU1O/EePGjZPr1X5a\nKrCivvchhPDLL7+Y2meffWZqsfFQZ5xxhqkdeOCBphb7PYp9Ll3hzgsA4A7NCwDgDs0LAOAOzQsA\n4A6BjR6m/vd9T7jxxhtN7ZBDDpGvbW1tNbWHH3647NdUqthnN2/evF6+EmSV5SF8qeEOFVYaNWqU\nXK/+TakgwurVq+V6FfhQ1N5d48ePl68tFoumdtxxx5nahAkT5Hq1R5kKocRs2LDB1Nrb201t8uTJ\ncn3qNJDuBjNiuPMCALhD8wIAuEPzAgC4Q/MCALhD8wIAuMN+Xl1QybYnnniiAlfS+2L776Smi66+\n+mpZnzZtWtL66dOny/qhhx6qyuznVSGl7uelxJJpaoyZShvGxkO9+OKLpvbaa6+ZmtqHLwQ9ymn7\n9u2mpsZDxUawqbSj2vMv9pmoUVKNjY2mFksfq7/JyJEjTe3YY4+V62fMmGFqKtWp/k4x7OcFAOiX\naF4AAHdoXgAAd2heAAB3CGx0w5IlS0yto6OjpGOuXbvW1Eod2bRgwQJZnzRpUtL6888/X9YPPvjg\nbl9TDyKwUSGlBjZULbbnndq7Su1TpQITIejRaO+//76pxfauUmOn1DV9++23ptbS0iKPqfb8U/th\nHXbYYXL90KFDTe2ggw4ytSOPPFKuVwEsVWtoaJDrhw8fbmrq808NeoVAYAMA0E/RvAAA7tC8AADu\n0LwAAO4Q2EB/QWCjQrIENpQs+zypcIb6DYtNc1CvVdM4VAgjhBDq6upMTYVL1H5YsWPu37/f1Kqr\nq01NTd0IQU/9UOGIWIhFnV9da6xXqPev/qZZ/s4ENgAA/RLNCwDgDs0LAOAOzQsA4A7NCwDgjt6w\nCQAqKJZMUyk69dpisSjXpyb7YlQyUSUg1XgpNcYpBL1vnho3p649BJ2sVAnA2Him1M9Uvc+YLMnC\n7uLOCwDgDs0LAOAOzQsA4A7NCwDgDoENABWVusdXTCzIoKSOl4pRgQ0VeFBjpGIhhkKhkHSe2PtU\n51fvKba+1HBFb4QzFO68AADu0LwAAO7QvAAA7tC8AADuENgA4EZqOCD2OjVNIzZ5QlGTK1LDEbEJ\nFer86jyqFju/ev9Zgi2l7sfVG7jzAgC4Q/MCALhD8wIAuEPzAgC4Q/MCALhD2hCAG6mjnGLJPCVL\niq6U88fWqv28UhOEsXqWkVd9LUWYijsvAIA7NC8AgDs0LwCAOzQvAIA7VVke7AEA0Bdw5wUAcIfm\nBQBwh+YFAHCH5gUAcIfmBQBwh+YFAHCH5gUAcIfmBQBwh+YFAHCH5gUAcIfmBQBwh+YFAHCH5gUA\ncIfmBQBwh+YFAHCH5gUAcIfmBQBwh+YFAHCH5gUAcIfmBQBwh+YFAHCH5gUAcIfmBQBwh+YFAHCH\n5gUAcIfmBQBw538AH/ARpijPUtIAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show_reconstructed_digits(X, outputs, \"./my_model_cache_frozen.ckpt\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true, + "deletable": true, + "editable": true + }, + "source": [ + "## Unsupervised pretraining for mnist" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "tf.reset_default_graph()\n", + "\n", + "n_inputs = 28 * 28\n", + "n_hidden1 = 300\n", + "n_hidden2 = 150\n", + "n_outputs = 10\n", + "\n", + "learning_rate = 0.01\n", + "l2_reg = 5e-4\n", + "\n", + "activation = tf.nn.elu\n", + "regularizer = tf.contrib.layers.l2_regularizer(l2_reg)\n", + "initializer = tf.contrib.layers.variance_scaling_initializer()\n", + "\n", + "X = tf.placeholder(tf.float32, [None, n_inputs])\n", + "y = tf.placeholder(tf.int32, [None])\n", + "\n", + "W1 = tf.Variable(initializer([n_inputs, n_hidden1]), dtype=tf.float32, name=\"W1\")\n", + "b1 = tf.Variable(tf.zeros([n_hidden1,]), name=\"b1\")\n", + "W2 = tf.Variable(initializer([n_hidden1, n_hidden2]), dtype=tf.float32, name=\"W2\")\n", + "b2 = tf.Variable(tf.zeros([n_hidden2,]), name=\"b2\")\n", + "W3 = tf.Variable(initializer([n_hidden2, n_outputs]), dtype=tf.float32, name=\"W3\")\n", + "b3 = tf.Variable(tf.zeros([n_outputs,]), name=\"b3\")\n", + "\n", + "h1 = activation(tf.nn.xw_plus_b(X, W1, b1))\n", + "h2 = activation(tf.nn.xw_plus_b(h1, W2, b2))\n", + "logits = tf.nn.xw_plus_b(h2, W3, b3)\n", + "\n", + "cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=y)\n", + "reg_loss = regularizer(W1) + regularizer(W2) + regularizer(W3)\n", + "loss = reg_loss + tf.reduce_mean(cross_entropy)\n", + "\n", + "train_op = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)\n", + "\n", + "correct = tf.nn.in_top_k(logits, y, 1)\n", + "accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))\n", + "\n", + "init = tf.global_variables_initializer()\n", + "pretrain_saver = tf.train.Saver([W1, W2, b1, b2])\n", + "saver = tf.train.Saver()" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 Train accuracy: 0.953333 Test accuracy: 0.9358\n", + "1 Train accuracy: 0.993333 Test accuracy: 0.9469\n", + "29% Train accuracy: 0.973333 Test accuracy: 0.9476\n", + "3 Train accuracy: 0.973333 Test accuracy: 0.9323\n" + ] + } + ], + "source": [ + "# regular training\n", + "n_epochs = 4\n", + "batch_size = 150\n", + "n_labeled_instances = 20000\n", + "\n", + "with tf.Session() as sess:\n", + " init.run()\n", + " for epoch in range(n_epochs):\n", + " n_batches = n_labeled_instances // batch_size\n", + " for iteration in range(n_batches):\n", + " print(\"\\r{}%\".format(100 * iteration // n_batches), end=\"\")\n", + " sys.stdout.flush()\n", + " indices = np.random.permutation(n_labeled_instances)[:batch_size]\n", + " X_batch, y_batch = mnist.train.images[indices], mnist.train.labels[indices]\n", + " sess.run(train_op, feed_dict={X: X_batch, y: y_batch})\n", + " accuracy_val = accuracy.eval(feed_dict={X: X_batch, y: y_batch})\n", + " print(\"\\r{}\".format(epoch), \"Train accuracy:\", accuracy_val, end=\" \")\n", + " saver.save(sess, \"./my_model_supervised.ckpt\")\n", + " accuracy_val = accuracy.eval(feed_dict={X: mnist.test.images, y: mnist.test.labels})\n", + " print(\"Test accuracy:\", accuracy_val)" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "INFO:tensorflow:Restoring parameters from ./my_model_cache_frozen.ckpt\n", + "0 Train accuracy: 0.926667\tTest accuracy: 0.9125\n", + "19% Train accuracy: 0.966667\tTest accuracy: 0.939\n", + "2 Train accuracy: 0.98\tTest accuracy: 0.9249\n", + "3 Train accuracy: 0.966667\tTest accuracy: 0.9286\n" + ] + } + ], + "source": [ + "## with pretraining\n", + "n_epochs = 4\n", + "batch_size = 150\n", + "n_labeled_instances = 20000\n", + "\n", + "#training_op = optimizer.minimize(loss, var_list=[weights3, biases3]) # Freeze layers 1 and 2 (optional)\n", + "\n", + "with tf.Session() as sess:\n", + " init.run()\n", + " pretrain_saver.restore(sess, \"./my_model_cache_frozen.ckpt\")\n", + " for epoch in range(n_epochs):\n", + " n_batches = n_labeled_instances // batch_size\n", + " for iteration in range(n_batches):\n", + " print(\"\\r{}%\".format(100 * iteration // n_batches), end=\"\")\n", + " sys.stdout.flush()\n", + " indices = np.random.permutation(n_labeled_instances)[:batch_size]\n", + " X_batch, y_batch = mnist.train.images[indices], mnist.train.labels[indices]\n", + " sess.run(train_op, feed_dict={X: X_batch, y: y_batch})\n", + " accuracy_val = accuracy.eval(feed_dict={X: X_batch, y: y_batch})\n", + " print(\"\\r{}\".format(epoch), \"Train accuracy:\", accuracy_val, end=\"\\t\")\n", + " saver.save(sess, \"./my_model_supervised_pretrained.ckpt\")\n", + " accuracy_val = accuracy.eval(feed_dict={X: mnist.test.images, y: mnist.test.labels})\n", + " print(\"Test accuracy:\", accuracy_val)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Stacked denoising autoencoder" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "tf.reset_default_graph()\n", + "\n", + "n_inputs = 28 * 28\n", + "n_hidden1 = 300\n", + "n_hidden2 = 150 # codings\n", + "n_hidden3 = n_hidden1\n", + "n_outputs = n_inputs\n", + "\n", + "learning_rate = 0.01\n", + "l2_reg = 1e-5\n", + "dropout_rate = 0.3\n", + "\n", + "activation = tf.nn.elu\n", + "regularizer = tf.contrib.layers.l2_regularizer(l2_reg)\n", + "initializer = tf.contrib.layers.variance_scaling_initializer()\n", + "\n", + "X = tf.placeholder(tf.float32, [None, n_inputs])\n", + "is_training = tf.placeholder_with_default(False, shape=[], name=\"is_training\")\n", + "X_drop = tf.layers.dropout(X, dropout_rate, training=is_training)\n", + "\n", + "W1 = tf.Variable(initializer([n_inputs, n_hidden1]), dtype=tf.float32, name=\"W1\")\n", + "b1 = tf.Variable(tf.zeros([n_hidden1,]), name=\"b1\")\n", + "W2 = tf.Variable(initializer([n_hidden1, n_hidden2]), dtype=tf.float32, name=\"W2\")\n", + "b2 = tf.Variable(tf.zeros([n_hidden2,]), name=\"b2\")\n", + "W3 = tf.transpose(W2, name=\"W3\")\n", + "b3 = tf.Variable(tf.zeros([n_hidden3,]), name=\"b3\")\n", + "W4 = tf.transpose(W1, name=\"W4\")\n", + "b4 = tf.Variable(tf.zeros([n_outputs,]), name=\"b4\")\n", + "\n", + "h1 = activation(tf.nn.xw_plus_b(X_drop, W1, b1))\n", + "h2 = activation(tf.nn.xw_plus_b(h1, W2, b2))\n", + "h3 = activation(tf.nn.xw_plus_b(h2, W3, b3))\n", + "outputs = tf.nn.xw_plus_b(h3, W4, b4)\n", + "\n", + "mse_loss = tf.reduce_mean(tf.square(outputs - X))\n", + "reg_loss = regularizer(W1) + regularizer(W2)\n", + "loss = mse_loss + reg_loss\n", + "\n", + "train_op = tf.train.AdamOptimizer(learning_rate).minimize(loss)\n", + "init = tf.global_variables_initializer()\n", + "saver = tf.train.Saver()" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 Train MSE: 0.0188708\n", + "1 Train MSE: 0.0135786\n", + "29% Train MSE: 0.0113397\n", + "3 Train MSE: 0.010279\n", + "4 Train MSE: 0.00961263\n", + "5 Train MSE: 0.00885574\n", + "69% Train MSE: 0.00939195\n", + "7 Train MSE: 0.00923494\n", + "8 Train MSE: 0.00853442\n", + "9 Train MSE: 0.0090277\n" + ] + } + ], + "source": [ + "n_epochs = 10\n", + "batch_size = 150\n", + "\n", + "with tf.Session() as sess:\n", + " init.run()\n", + " for epoch in range(n_epochs):\n", + " n_batches = mnist.train.num_examples // batch_size\n", + " for iteration in range(n_batches):\n", + " print(\"\\r{}%\".format(100 * iteration // n_batches), end=\"\")\n", + " sys.stdout.flush()\n", + " X_batch, _ = mnist.train.next_batch(batch_size)\n", + " sess.run(train_op, feed_dict={X: X_batch, is_training: True})\n", + " mse_train = mse_loss.eval(feed_dict={X: X_batch, is_training: False})\n", + " print(\"\\r{}\".format(epoch), \"Train MSE:\", mse_train)\n", + " saver.save(sess, \"./my_model_stacked_denoising.ckpt\")" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "INFO:tensorflow:Restoring parameters from ./my_model_stacked_denoising.ckpt\n" + ] + }, + { + "data": { + "image/png": "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\nAQDCoXkBAMIhsDHM2tvbTW3x4sVZa59//nlZX7BgQUnXBIwkKhzhhQOUQsIF6lxqPJIXONi9e7ep\nrV27Nuv8N9xwgzzmsmXLTE2FSLwQivqsGmPlrc8dL+WtV981N5hTCp68AADh0LwAAOHQvAAA4dC8\nAADhENgYZk8//bSpff3111lrL7nkElkv94tPYKTxAhMqnKHCCaqWkp480dvba2oqaJVSSm+//bap\nvfvuu6ZWW1traueff748ZkNDQ9Y1qRBFSvmBCW/ChlLI1JPc9eXGkxcAIByaFwAgHJoXACAcmhcA\nIByaFwAgHNKGZbJt2zZZ/+tf/3piLwQYxbzE3fHUyCSvrpJxu3btkuu3bNliauq3f9lll5laS0uL\nPKZKBqp9w1RSMiU93io3lVkIbz+xE7F3l8KTFwAgHJoXACAcmhcAIByaFwAgHAIbZaL29EkppR9+\n+CFrfWtrq6mpETPAWOCNIlKhARVE8EIEfX19ptbR0WFq+/fvl+t37txpajNmzDA1Fc5oamqSx1Tf\naeLEiaamghleXY2X8u5pqXtv5QY2vGMWG/jgyQsAEA7NCwAQDs0LABAOzQsAEA6BjQr4zW9+Y2pv\nvPGGqRHYQFTlfjn/MxVuUEGEgYGB7OtS1+T99q644gpTW7p0qampvbu8Y6oQiQqheNNF1PdXtULu\n/XBMzSj3MXnyAgCEQ/MCAIRD8wIAhEPzAgCEQ/MCAIQzrkJ7sVRmAxiMZvnzbFBWbW1tFf095yYI\nC/msl1b0Riwdr6qqytQK2U8r9zwp5Y9yqtS+W8Vobm4e8kvx5AUACIfmBQAIh+YFAAiH5gUACKdS\ngQ0AAIrGkxcAIByaFwAgHJoXACAcmhcAIByaFwAgHJoXACAcmhcAIByaFwAgHJoXACAcmhcAIBya\nFwAgHJoXACAcmhcAIByaFwAgHJoXACAcmhcAIByaFwAgHJoXACAcmhcAIByaFwAgHJoXACAcmhcA\nIByaFwAgHJoXACAcmhcAIByaFwAgHJoXACAcmhcAIByaFwAgnPEVOu+PFTovRq9xlb6Asaq9vZ3f\nc4Zx4/R/oj/+yO07XmNj45C/Z568AADh0LwAAOHQvAAA4VTqnRcAlIX3LklR75fUeu+Yx44dK2l9\n7jWddJJ9rij1mIW8Wyv1PZy61nK/2+PJCwAQDs0LABAOzQsAEA7NCwAQDs0LABAOaUMAo46XzFP1\n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\nJf2eVRDBCwt5e1odzxulpAIXH374oamp32NKeu8wFfhQVNgkJf2d1PdXY7RS0ntnzZ0719Tmz58v\n16t7pf5NJk2aJNc3NTWZmgpsFDIyqrGxcch/aJ68AADh0LwAAOHQvAAA4dC8AADhENjAaEFgo0JK\nDWyov0HeNAn1WRVkUFMnUkqpqqrK1NQ+Vz/88INcr8INauJMZ2dn1nV6x1SfVWGRlPR3nThxoqmp\n7+4dV4VLvPOrvddygzUeAhsAgFGJ5gUACIfmBQAIh+YFAAiH5gUACIf9vACMON54KJUMVLy0oErG\nqbFFXlpRXZdKQNbX15ual/ZTVFrR++7qmlTazxtPpa5LJSi98U4VSqzz5AUAiIfmBQAIh+YFAAiH\n5gUACIfABoCKUuECLxyg9olSvPFSKtygxjMNDAxknSclfa0qHFHIyCR1/d41qcBFIddfqlJHQRWL\nJy8AQDg0LwBAODQvAEA4NC8AQDgENgCMON7UBlVXgQFvmoUKMqj1hey9pfa5yt2jy6OuX00H8c6v\n7pMXglHXdSJDGMWeiycvAEA4NC8AQDg0LwBAODQvAEA4NC8AQDikDQGEoRJzKq3mpRW9xF2uvr6+\nrHN546kUdf2FJCBz9wnz7kmlxjv9rNj9wHjyAgCEQ/MCAIRD8wIAhEPzAgCEM67Yl2UAAFQKT14A\ngHBoXgCAcGheAIBwaF4AgHBoXgCAcGheAIBwaF4AgHBoXgCAcGheAIBwaF4AgHBoXgCAcGheAIBw\naF4AgHBoXgCAcGheAIBwaF4AgHBoXgCAcGheAIBwaF4AgHBoXgCAcGheAIBwaF4AgHBoXgCAcGhe\nAIBwaF4AgHBoXgCAcP4LkMpAZYOBNGwAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show_reconstructed_digits(X, outputs, \"./my_model_stacked_denoising.ckpt\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Visualizing the extracted features" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "INFO:tensorflow:Restoring parameters from ./my_model_stacked_denoising.ckpt\n" + ] + } + ], + "source": [ + "with tf.Session() as sess:\n", + " saver.restore(sess, \"./my_model_stacked_denoising.ckpt\")\n", + " W1_val = W1.eval()" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saving figure extracted_features_plot\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "for i in range(5):\n", + " plt.subplot(1, 5, i+1)\n", + " plot_image(W1_val.T[i])\n", + "\n", + "save_fig(\"extracted_features_plot\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Sparse Autoencoder" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "d:\\anaconda3\\envs\\tf_new\\lib\\site-packages\\ipykernel\\__main__.py:3: RuntimeWarning: divide by zero encountered in true_divide\n", + " app.launch_new_instance()\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saving figure sparsity_loss_plot\n" + ] + }, + { + "data": { + "image/png": "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\nMsYYE5D+H3X4cGCzjDwQAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "p = 0.1\n", + "q = np.linspace(0, 1, 500)\n", + "kl_div = p * np.log(p / q) + (1 - p) * np.log((1 - p) / (1 - q))\n", + "mse = (p - q)**2\n", + "plt.plot([p, p], [0, 0.3], \"k:\")\n", + "plt.text(0.05, 0.32, \"Target\\nsparsity\", fontsize=14)\n", + "plt.plot(q, kl_div, \"b-\", label=\"KL divergence\")\n", + "plt.plot(q, mse, \"r--\", label=\"MSE\")\n", + "plt.legend(loc=\"upper left\")\n", + "plt.xlabel(\"Actual sparsity\")\n", + "plt.ylabel(\"Cost\", rotation=0)\n", + "plt.axis([0, 1, 0, 0.95])\n", + "save_fig(\"sparsity_loss_plot\")" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# KL divergence\n", + "def kl_divergence(p, q):\n", + " return p * tf.log(p / q) + (1 - p) * tf.log((1 - p) / (1 - q))" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "tf.reset_default_graph()\n", + "\n", + "n_inputs = 28 * 28\n", + "n_hidden = 1000 # sparse coding\n", + "n_outputs = n_inputs\n", + "\n", + "learning_rate = 0.01\n", + "sparsity_target = 0.1\n", + "sparsity_weight = 0.2\n", + "\n", + "activation = tf.nn.sigmoid\n", + "initializer = tf.contrib.layers.variance_scaling_initializer()\n", + "\n", + "X = tf.placeholder(tf.float32, [None, n_inputs])\n", + "\n", + "W1 = tf.Variable(initializer([n_inputs, n_hidden]), dtype=tf.float32, name=\"W1\")\n", + "W2 = tf.Variable(initializer([n_hidden, n_outputs]), dtype=tf.float32, name=\"W2\")\n", + "b1 = tf.Variable(tf.zeros([n_hidden,]), name=\"b1\")\n", + "b2 = tf.Variable(tf.zeros([n_outputs,]), name=\"b2\")\n", + "\n", + "h1 = activation(tf.nn.xw_plus_b(X, W1, b1))\n", + "outputs = tf.nn.xw_plus_b(h1, W2, b2)\n", + "\n", + "mse_loss = tf.reduce_mean(tf.square(outputs - X))\n", + "sparsity_loss = tf.reduce_mean(kl_divergence(sparsity_target, tf.reduce_mean(h1, axis=0)))\n", + "loss = mse_loss + sparsity_weight * sparsity_loss\n", + "\n", + "train_op = tf.train.AdamOptimizer(learning_rate).minimize(loss)\n", + "\n", + "init = tf.global_variables_initializer()\n", + "saver = tf.train.Saver()" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 Train MSE: 0.089448 \tSparsity loss: 0.31594 \tTotal loss: 0.152636\n", + "1 Train MSE: 0.0798196 \tSparsity loss: 0.301433 \tTotal loss: 0.140106\n", + "2 Train MSE: 0.0702621 \tSparsity loss: 0.307248 \tTotal loss: 0.131712\n", + "3 Train MSE: 0.072368 \tSparsity loss: 0.263305 \tTotal loss: 0.125029\n", + "4 Train MSE: 0.0658286 \tSparsity loss: 0.231783 \tTotal loss: 0.112185\n", + "5 Train MSE: 0.0573753 \tSparsity loss: 0.152271 \tTotal loss: 0.0878295\n", + "6 Train MSE: 0.0461967 \tSparsity loss: 0.091913 \tTotal loss: 0.0645794\n", + "7 Train MSE: 0.0323527 \tSparsity loss: 0.0477101 \tTotal loss: 0.0418947\n", + "8 Train MSE: 0.0224417 \tSparsity loss: 0.0230307 \tTotal loss: 0.0270478\n", + "9 Train MSE: 0.0169484 \tSparsity loss: 0.014174 \tTotal loss: 0.0197832\n", + "10 Train MSE: 0.0135708 \tSparsity loss: 0.00927507 \tTotal loss: 0.0154258\n", + "11 Train MSE: 0.0115894 \tSparsity loss: 0.0081538 \tTotal loss: 0.0132201\n", + "12 Train MSE: 0.0103312 \tSparsity loss: 0.00816472 \tTotal loss: 0.0119641\n", + "13 Train MSE: 0.00917437 \tSparsity loss: 0.00835424 \tTotal loss: 0.0108452\n", + "14 Train MSE: 0.0083915 \tSparsity loss: 0.00798041 \tTotal loss: 0.00998758\n", + "15 Train MSE: 0.00779623 \tSparsity loss: 0.00808132 \tTotal loss: 0.00941249\n", + "16 Train MSE: 0.00734944 \tSparsity loss: 0.00785454 \tTotal loss: 0.00892035\n", + "17 Train MSE: 0.00700855 \tSparsity loss: 0.00766381 \tTotal loss: 0.00854131\n", + "18 Train MSE: 0.00669476 \tSparsity loss: 0.00779145 \tTotal loss: 0.00825305\n", + "19 Train MSE: 0.00650377 \tSparsity loss: 0.00698666 \tTotal loss: 0.0079011\n", + "20 Train MSE: 0.00600064 \tSparsity loss: 0.00718371 \tTotal loss: 0.00743738\n", + "21 Train MSE: 0.00566541 \tSparsity loss: 0.0073112 \tTotal loss: 0.00712765\n", + "22 Train MSE: 0.00574734 \tSparsity loss: 0.00675132 \tTotal loss: 0.0070976\n", + "23 Train MSE: 0.00525059 \tSparsity loss: 0.00684258 \tTotal loss: 0.00661911\n", + "24 Train MSE: 0.00503834 \tSparsity loss: 0.00657567 \tTotal loss: 0.00635348\n", + "25 Train MSE: 0.00496254 \tSparsity loss: 0.00634394 \tTotal loss: 0.00623133\n", + "26 Train MSE: 0.00478003 \tSparsity loss: 0.00625404 \tTotal loss: 0.00603084\n", + "27 Train MSE: 0.00474681 \tSparsity loss: 0.00605509 \tTotal loss: 0.00595783\n", + "28 Train MSE: 0.00474311 \tSparsity loss: 0.00615628 \tTotal loss: 0.00597437\n", + "29 Train MSE: 0.00428011 \tSparsity loss: 0.00605045 \tTotal loss: 0.0054902\n", + "30 Train MSE: 0.00418255 \tSparsity loss: 0.00616588 \tTotal loss: 0.00541573\n", + "31 Train MSE: 0.00419088 \tSparsity loss: 0.00580817 \tTotal loss: 0.00535251\n", + "32 Train MSE: 0.00407085 \tSparsity loss: 0.0056494 \tTotal loss: 0.00520073\n", + "33 Train MSE: 0.00385356 \tSparsity loss: 0.00523736 \tTotal loss: 0.00490103\n", + "34 Train MSE: 0.00382184 \tSparsity loss: 0.00522718 \tTotal loss: 0.00486727\n", + "35 Train MSE: 0.00372391 \tSparsity loss: 0.00511245 \tTotal loss: 0.0047464\n", + "36 Train MSE: 0.00357969 \tSparsity loss: 0.00498948 \tTotal loss: 0.00457758\n", + "37 Train MSE: 0.00381227 \tSparsity loss: 0.00487638 \tTotal loss: 0.00478755\n", + "38 Train MSE: 0.00352203 \tSparsity loss: 0.00481535 \tTotal loss: 0.0044851\n", + "39 Train MSE: 0.00347288 \tSparsity loss: 0.00428925 \tTotal loss: 0.00433073\n", + "40 Train MSE: 0.00329288 \tSparsity loss: 0.00448029 \tTotal loss: 0.00418894\n", + "41 Train MSE: 0.00351159 \tSparsity loss: 0.00426345 \tTotal loss: 0.00436428\n", + "42 Train MSE: 0.00350584 \tSparsity loss: 0.00429598 \tTotal loss: 0.00436504\n", + "43 Train MSE: 0.00330488 \tSparsity loss: 0.00410366 \tTotal loss: 0.00412561\n", + "44 Train MSE: 0.00327868 \tSparsity loss: 0.00377962 \tTotal loss: 0.0040346\n", + "45 Train MSE: 0.00306268 \tSparsity loss: 0.00394039 \tTotal loss: 0.00385076\n", + "46 Train MSE: 0.00318153 \tSparsity loss: 0.00375002 \tTotal loss: 0.00393153\n", + "47 Train MSE: 0.00303979 \tSparsity loss: 0.00397687 \tTotal loss: 0.00383517\n", + "48 Train MSE: 0.00312536 \tSparsity loss: 0.00382304 \tTotal loss: 0.00388996\n", + "49 Train MSE: 0.00287534 \tSparsity loss: 0.00353072 \tTotal loss: 0.00358149\n", + "50 Train MSE: 0.00305251 \tSparsity loss: 0.00320351 \tTotal loss: 0.00369321\n", + "51 Train MSE: 0.00286479 \tSparsity loss: 0.0029645 \tTotal loss: 0.00345769\n", + "52 Train MSE: 0.00285689 \tSparsity loss: 0.00305719 \tTotal loss: 0.00346833\n", + "53 Train MSE: 0.00288925 \tSparsity loss: 0.00286612 \tTotal loss: 0.00346248\n", + "54 Train MSE: 0.00278685 \tSparsity loss: 0.00280555 \tTotal loss: 0.00334796\n", + "55 Train MSE: 0.00258185 \tSparsity loss: 0.00270222 \tTotal loss: 0.00312229\n", + "56 Train MSE: 0.00271206 \tSparsity loss: 0.00252305 \tTotal loss: 0.00321667\n", + "57 Train MSE: 0.00314271 \tSparsity loss: 0.00249987 \tTotal loss: 0.00364268\n", + "58 Train MSE: 0.0027225 \tSparsity loss: 0.00239151 \tTotal loss: 0.00320081\n", + "59 Train MSE: 0.00248702 \tSparsity loss: 0.00235511 \tTotal loss: 0.00295804\n", + "60 Train MSE: 0.00274784 \tSparsity loss: 0.00229175 \tTotal loss: 0.00320619\n", + "61 Train MSE: 0.0023637 \tSparsity loss: 0.0021467 \tTotal loss: 0.00279304\n", + "62 Train MSE: 0.00376068 \tSparsity loss: 0.0017723 \tTotal loss: 0.00411514\n", + "63 Train MSE: 0.00233923 \tSparsity loss: 0.00219192 \tTotal loss: 0.00277762\n", + "64 Train MSE: 0.00231539 \tSparsity loss: 0.00185233 \tTotal loss: 0.00268585\n", + "65 Train MSE: 0.0022342 \tSparsity loss: 0.00201337 \tTotal loss: 0.00263687\n", + "66 Train MSE: 0.00308808 \tSparsity loss: 0.00189729 \tTotal loss: 0.00346754\n", + "67 Train MSE: 0.0021982 \tSparsity loss: 0.00183677 \tTotal loss: 0.00256555\n", + "68 Train MSE: 0.00226939 \tSparsity loss: 0.00162599 \tTotal loss: 0.00259459\n", + "69 Train MSE: 0.00247374 \tSparsity loss: 0.00150849 \tTotal loss: 0.00277544\n", + "70 Train MSE: 0.00228837 \tSparsity loss: 0.00148242 \tTotal loss: 0.00258486\n", + "71 Train MSE: 0.0024456 \tSparsity loss: 0.00147809 \tTotal loss: 0.00274121\n", + "72 Train MSE: 0.00210597 \tSparsity loss: 0.00138623 \tTotal loss: 0.00238321\n", + "73 Train MSE: 0.0021107 \tSparsity loss: 0.00129582 \tTotal loss: 0.00236987\n", + "74 Train MSE: 0.0022424 \tSparsity loss: 0.00129065 \tTotal loss: 0.00250053\n", + "75 Train MSE: 0.00233301 \tSparsity loss: 0.00110327 \tTotal loss: 0.00255366\n", + "76 Train MSE: 0.00219297 \tSparsity loss: 0.00117603 \tTotal loss: 0.00242817\n", + "77 Train MSE: 0.00248895 \tSparsity loss: 0.00109521 \tTotal loss: 0.002708\n", + "78 Train MSE: 0.002521 \tSparsity loss: 0.00096837 \tTotal loss: 0.00271467\n", + "79 Train MSE: 0.00189789 \tSparsity loss: 0.00103555 \tTotal loss: 0.002105\n", + "80 Train MSE: 0.00280811 \tSparsity loss: 0.0010167 \tTotal loss: 0.00301145\n", + "81 Train MSE: 0.00230722 \tSparsity loss: 0.000979726 \tTotal loss: 0.00250317\n", + "82 Train MSE: 0.00351125 \tSparsity loss: 0.000846072 \tTotal loss: 0.00368046\n", + "83 Train MSE: 0.00218575 \tSparsity loss: 0.000720168 \tTotal loss: 0.00232979\n", + "84 Train MSE: 0.00186479 \tSparsity loss: 0.00083085 \tTotal loss: 0.00203096\n", + "85 Train MSE: 0.00191433 \tSparsity loss: 0.000784804 \tTotal loss: 0.00207129\n", + "86 Train MSE: 0.00217137 \tSparsity loss: 0.00075687 \tTotal loss: 0.00232275\n", + "87 Train MSE: 0.00290488 \tSparsity loss: 0.000699203 \tTotal loss: 0.00304472\n", + "88 Train MSE: 0.0022122 \tSparsity loss: 0.000660279 \tTotal loss: 0.00234425\n", + "89 Train MSE: 0.00301047 \tSparsity loss: 0.000502598 \tTotal loss: 0.00311099\n", + "90 Train MSE: 0.00225816 \tSparsity loss: 0.000577241 \tTotal loss: 0.00237361\n", + "91 Train MSE: 0.00226497 \tSparsity loss: 0.00067302 \tTotal loss: 0.00239957\n", + "92 Train MSE: 0.00283404 \tSparsity loss: 0.000533305 \tTotal loss: 0.0029407\n", + "93 Train MSE: 0.00213362 \tSparsity loss: 0.000496102 \tTotal loss: 0.00223284\n", + "94 Train MSE: 0.0039725 \tSparsity loss: 0.000455502 \tTotal loss: 0.0040636\n", + "95 Train MSE: 0.00228322 \tSparsity loss: 0.000475096 \tTotal loss: 0.00237824\n", + "96 Train MSE: 0.00336009 \tSparsity loss: 0.000467131 \tTotal loss: 0.00345352\n", + "97 Train MSE: 0.00208409 \tSparsity loss: 0.000463994 \tTotal loss: 0.00217689\n", + "98 Train MSE: 0.00231182 \tSparsity loss: 0.000605519 \tTotal loss: 0.00243292\n", + "99 Train MSE: 0.00337147 \tSparsity loss: 0.000389955 \tTotal loss: 0.00344946\n" + ] + } + ], + "source": [ + "n_epochs = 100\n", + "batch_size = 1000\n", + "\n", + "with tf.Session() as sess:\n", + " init.run()\n", + " for epoch in range(n_epochs):\n", + " n_batches = mnist.train.num_examples // batch_size\n", + " for iteration in range(n_batches):\n", + " print(\"\\r{}%\".format(100 * iteration // n_batches), end=\"\")\n", + " sys.stdout.flush()\n", + " X_batch, y_batch = mnist.train.next_batch(batch_size)\n", + " sess.run(train_op, feed_dict={X: X_batch})\n", + " mse_val, sparsity_loss_val, loss_val = sess.run([mse_loss, sparsity_loss, loss], feed_dict={X: X_batch})\n", + " print(\"\\r{}\".format(epoch), \"Train MSE:\", mse_val, \"\\tSparsity loss:\", sparsity_loss_val, \"\\tTotal loss:\", loss_val)\n", + " saver.save(sess, \"./my_model_sparse.ckpt\")" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "INFO:tensorflow:Restoring parameters from ./my_model_sparse.ckpt\n" + ] + }, + { + "data": { + "image/png": "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\n5ZrU66qpH9GEkAMHDrjaunXrXO2ee+5xNRUsMdP7oalgSrRHl7pWtfdWdE/V5AsVeImmbqhrVRNC\nIlG4phZ+eQEA0qF5AQDSoXkBANKheQEA0qF5AQDSaVDjTs6AupwUs1rZRk+Ydv39/e77rNJuZnrv\nL5UgjNJqKq2o9n5SCT4zs+7ublcbGBhwtSgBp8YelY6MiqgUnzp/NF5JpQir7Mel7rW6f1H6WaUg\n1WcaXZOqd3R01Pw+88sLAJAOzQsAkA7NCwCQDs0LAJBOvQIbAABMGr+8AADp0LwAAOnQvAAA6dC8\nAADp0LwAAOnQvAAA6dC8AADp0LwAAOnQvAAA6dC8AADp0LwAAOnQvAAA6dC8AADp0LwAAOnQvAAA\n6dC8AADp0LwAAOnQvAAA6dC8AADp0LwAAOnQvAAA6dC8AADp0LwAAOnQvAAA6dC8AADp0LwAAOnQ\nvAAA6dC8AADp0LwAAOnMrdN5367TeTF7NdT7As5V/f397vs8Z84ceezbb/uv/ty5/p+hN998U64/\nfPiwqy1btszVRkdH5fpTp065WktLi6s1NjbK9RMTE6721ltvuZq6/oULFxZfk3rN6J42NPg/fXX9\nvb29cr16/+r88+fPl+vVseozPX78uFyvjm1paan5feaXFwAgHZoXACAdmhcAIJ0G9f9BnwE888J0\n45lXnQwMDLjv83nn6f9drOonT550tej50IkTJ1xNPXNRz4GicynR8yV1/WNjY66mnuNE16SeJQ0O\nDrqaejYVnUv9ux49R1T3Tz0zU+/TzKy5ubnoXPPmzZPr1WfS0dHBMy8AwOxD8wIApEPzAgCkQ/MC\nAKRD8wIApFOvCRsAZgmVootSzOPj466m0nZRKrA07Vcl2bdgwQJXU1MvorpK20VpS0VN7WhtbS1+\nTZXsU2nBaL1KcKpalMBUaUV1n6LzR5M3auGXFwAgHZoXACAdmhcAIB2aFwAgHQIb0+QXv/iFrKut\nGV544QVXu+eee4rP9bWvfc3V1q1b52of+9jHil8TmCz1ID4KTJSOElLBDjMduFC16PxNTU1F53r2\n2Wfl+tdee83VXn31VVfbtWuXq0Xjma699lpXW79+vatdccUVcr0Kx6iaClaY6XtSus2LmQ53qFFQ\nUTAjGhtVC7+8AADp0LwAAOnQvAAA6dC8AADpsJ/XJHzpS19ytR//+Md1uJL/9/73v9/VnnnmGXls\n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\ncujQIfd9jh7uq8CFClFEEy7UsWoah5pQYWbW0tLiatHeXYrae0u9J/Wa6jgzff0q8BK9J7WfmNo7\nTE0nMdN7n6nrj0I4KnDR2NjoakNDQ3K92k+spaWFwAYAYPaheQEA0qF5AQDSoXkBANKheQEA0iFt\niNmCtGGdjI6Ouu9ztJ+XqqtRSNGecerfKzXKKBovVZrsi9KS0T5jJeeP0nbqNVUqUr1PM53MVK8Z\n7Zul1qu04Pj4uFyvUpBNTU2uFn0m6nUXL15M2hAAMPvQvAAA6dC8AADp0LwAAOnoJ2gAUEiNF4qo\nvadUCGNgYECuV+ECFW6IghVqnykVGIhGKam6un4VTogCEyqIoV5TXbuZDreoY6uMd1L3L9qPS4U7\n1DVF47GiIEct/PICAKRD8wIApEPzAgCkQ/MCAKRDYAPAlKiH89GEDBWOUPs5Rft5lQYuoj261ISP\n6FpLqWkS6jqjqSMqsKDCFSqYYqYnXKhwRRSMUO9fBUaiEIwKfETTQKYTv7wAAOnQvAAA6dC8AADp\n0LwAAOnQvAAA6ZA2BDAlauxPNIpIJfNUCm/BggVyvRpFpZKFKoFnZtbR0eFqw8PDrlYlWaeShSrB\nF6X91Ho1cikaWaXuv0omRns3qveq7l/0maj3qq41SpBONu3JLy8AQDo0LwBAOjQvAEA6NC8AQDoN\n0UM8AADOVvzyAgCkQ/MCAKRD8wIApEPzAgCkQ/MCAKRD8wIApEPzAgCkQ/MCAKRD8wIApEPzAgCk\nQ/MCAKRD8wIApEPzAgCkQ/MCAKRD8wIApEPzAgCkQ/MCAKRD8wIApEPzAgCkQ/MCAKRD8wIApEPz\nAgCkQ/MCAKRD8wIApEPzAgCkQ/MCAKTzf6gyd5oBjLZ5AAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "show_reconstructed_digits(X, outputs, \"./my_model_sparse.ckpt\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Variational Autoencoder" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from functools import partial\n", + "\n", + "tf.reset_default_graph()\n", + "\n", + "n_inputs = 28 * 28\n", + "n_hidden1 = 500\n", + "n_hidden2 = 500\n", + "n_hidden3 = 20 # latent coding\n", + "n_hidden4 = n_hidden2\n", + "n_hidden5 = n_hidden1\n", + "n_outputs = n_inputs\n", + "\n", + "learning_rate = 1e-3\n", + "\n", + "dense_layer = partial(tf.layers.dense, activation=tf.nn.elu, \n", + " kernel_initializer=tf.contrib.layers.variance_scaling_initializer())\n", + "\n", + "X = tf.placeholder(tf.float32, [None, n_inputs])\n", + "\n", + "h1 = dense_layer(X, n_hidden1)\n", + "h2 = dense_layer(h1, n_hidden2)\n", + "h3_mean = dense_layer(h2, n_hidden3, activation=None)\n", + "h3_log_gamma = dense_layer(h2, n_hidden3, activation=None)\n", + "noise = tf.random_normal(tf.shape(h3_mean), dtype=tf.float32)\n", + "h3 = h3_mean + noise * tf.exp(0.5 * h3_log_gamma)\n", + "h4 = dense_layer(h3, n_hidden4)\n", + "h5 = dense_layer(h4, n_hidden5)\n", + "logits = dense_layer(h5, n_outputs, activation=None)\n", + "outputs = tf.sigmoid(logits)\n", + "\n", + "reconstruction_loss = tf.reduce_sum(tf.nn.sigmoid_cross_entropy_with_logits(logits=logits, labels=X))\n", + "latent_loss = 0.5 * tf.reduce_sum(tf.exp(h3_log_gamma) + tf.square(h3_mean) - 1 - h3_log_gamma)\n", + "loss = reconstruction_loss + latent_loss\n", + "\n", + "train_op = tf.train.AdamOptimizer(learning_rate).minimize(loss)\n", + "\n", + "init = tf.global_variables_initializer()\n", + "saver = tf.train.Saver()" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 Train cost: 17875.2 \tReconstruction loss: 14240.6 \tLatent loss: 3634.61\n", + "19% Train cost: 17548.1 \tReconstruction loss: 13777.4 \tLatent loss: 3770.78\n", + "2 Train cost: 17034.8 \tReconstruction loss: 13168.9 \tLatent loss: 3865.9\n", + "39% Train cost: 16482.2 \tReconstruction loss: 12694.2 \tLatent loss: 3788.05\n", + "49% Train cost: 16032.7 \tReconstruction loss: 12276.8 \tLatent loss: 3755.82\n", + "5 Train cost: 15633.8 \tReconstruction loss: 11945.7 \tLatent loss: 3688.03\n", + "6 Train cost: 15861.8 \tReconstruction loss: 12043.6 \tLatent loss: 3818.26\n", + "7 Train cost: 16033.8 \tReconstruction loss: 12243.4 \tLatent loss: 3790.37\n", + "8 Train cost: 15669.4 \tReconstruction loss: 11919.0 \tLatent loss: 3750.39\n", + "9 Train cost: 15610.7 \tReconstruction loss: 11797.2 \tLatent loss: 3813.54\n", + "10 Train cost: 15734.4 \tReconstruction loss: 12052.3 \tLatent loss: 3682.09\n", + "11 Train cost: 15623.2 \tReconstruction loss: 11804.1 \tLatent loss: 3819.05\n", + "12 Train cost: 15977.3 \tReconstruction loss: 12092.2 \tLatent loss: 3885.17\n", + "13 Train cost: 15843.5 \tReconstruction loss: 12004.9 \tLatent loss: 3838.61\n", + "14 Train cost: 15393.1 \tReconstruction loss: 11578.9 \tLatent loss: 3814.25\n", + "15 Train cost: 15663.0 \tReconstruction loss: 11889.6 \tLatent loss: 3773.32\n", + "16 Train cost: 15253.1 \tReconstruction loss: 11408.1 \tLatent loss: 3844.96\n", + "17 Train cost: 14680.3 \tReconstruction loss: 11130.2 \tLatent loss: 3550.09\n", + "18 Train cost: 15194.4 \tReconstruction loss: 11436.9 \tLatent loss: 3757.49\n", + "19 Train cost: 15213.5 \tReconstruction loss: 11517.4 \tLatent loss: 3696.06\n", + "20% Train cost: 15504.4 \tReconstruction loss: 11723.2 \tLatent loss: 3781.17\n", + "21 Train cost: 14657.8 \tReconstruction loss: 10954.8 \tLatent loss: 3703.0\n", + "22 Train cost: 14923.6 \tReconstruction loss: 11239.8 \tLatent loss: 3683.8\n", + "23 Train cost: 15046.8 \tReconstruction loss: 11250.5 \tLatent loss: 3796.34\n", + "24 Train cost: 14317.8 \tReconstruction loss: 10749.9 \tLatent loss: 3567.96\n", + "25 Train cost: 15251.5 \tReconstruction loss: 11554.8 \tLatent loss: 3696.7\n", + "26 Train cost: 14774.3 \tReconstruction loss: 11169.2 \tLatent loss: 3605.05\n", + "27 Train cost: 15071.6 \tReconstruction loss: 11280.5 \tLatent loss: 3791.07\n", + "28 Train cost: 14530.7 \tReconstruction loss: 10921.0 \tLatent loss: 3609.75\n", + "29% Train cost: 14655.2 \tReconstruction loss: 10987.5 \tLatent loss: 3667.69\n", + "30% Train cost: 14957.4 \tReconstruction loss: 11297.5 \tLatent loss: 3659.91\n", + "31 Train cost: 14998.9 \tReconstruction loss: 11261.2 \tLatent loss: 3737.73\n", + "32 Train cost: 14851.5 \tReconstruction loss: 11157.3 \tLatent loss: 3694.14\n", + "33 Train cost: 14992.6 \tReconstruction loss: 11296.3 \tLatent loss: 3696.26\n", + "34 Train cost: 14449.3 \tReconstruction loss: 10744.7 \tLatent loss: 3704.64\n", + "35 Train cost: 15177.0 \tReconstruction loss: 11381.1 \tLatent loss: 3795.89\n", + "36 Train cost: 15058.1 \tReconstruction loss: 11355.4 \tLatent loss: 3702.67\n", + "37 Train cost: 14821.3 \tReconstruction loss: 11129.8 \tLatent loss: 3691.44\n", + "38 Train cost: 14752.2 \tReconstruction loss: 11011.3 \tLatent loss: 3740.84\n", + "39 Train cost: 14596.8 \tReconstruction loss: 10949.4 \tLatent loss: 3647.42\n", + "40 Train cost: 14694.0 \tReconstruction loss: 10995.9 \tLatent loss: 3698.13\n", + "41 Train cost: 14499.3 \tReconstruction loss: 10767.7 \tLatent loss: 3731.55\n", + "42 Train cost: 14830.7 \tReconstruction loss: 11197.3 \tLatent loss: 3633.34\n", + "43% Train cost: 14656.4 \tReconstruction loss: 10998.3 \tLatent loss: 3658.07\n", + "44 Train cost: 14954.2 \tReconstruction loss: 11257.9 \tLatent loss: 3696.24\n", + "45 Train cost: 15002.2 \tReconstruction loss: 11240.9 \tLatent loss: 3761.3\n", + "46 Train cost: 14050.2 \tReconstruction loss: 10452.3 \tLatent loss: 3597.89\n", + "47% Train cost: 14473.6 \tReconstruction loss: 10740.6 \tLatent loss: 3733.02\n", + "48 Train cost: 14555.2 \tReconstruction loss: 10851.3 \tLatent loss: 3703.93\n", + "49 Train cost: 14944.6 \tReconstruction loss: 11207.9 \tLatent loss: 3736.65\n" + ] + } + ], + "source": [ + "n_epochs = 50\n", + "batch_size = 150\n", + "\n", + "with tf.Session() as sess:\n", + " init.run()\n", + " for epoch in range(n_epochs):\n", + " n_batches = mnist.train.num_examples // batch_size\n", + " for iteration in range(n_batches):\n", + " print(\"\\r{}%\".format(100 * iteration // n_batches), end=\"\")\n", + " sys.stdout.flush()\n", + " X_batch, y_batch = mnist.train.next_batch(batch_size)\n", + " sess.run(train_op, feed_dict={X: X_batch})\n", + " cost_val, reconstruction_loss_val, latent_loss_val = sess.run([loss, reconstruction_loss, latent_loss], feed_dict={X: X_batch})\n", + " print(\"\\r{}\".format(epoch), \"Train cost:\", cost_val, \"\\tReconstruction loss:\", reconstruction_loss_val, \"\\tLatent loss:\", latent_loss_val)\n", + " saver.save(sess, \"./my_model_variational.ckpt\")" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "INFO:tensorflow:Restoring parameters from ./my_model_variational.ckpt\n" + ] + } + ], + "source": [ + "# encode\n", + "n_digits = 3\n", + "X_test, y_test = mnist.test.next_batch(batch_size)\n", + "codings = h3\n", + "\n", + "with tf.Session() as sess:\n", + " saver.restore(sess, \"./my_model_variational.ckpt\")\n", + " codings_val = codings.eval(feed_dict={X: X_test})" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "INFO:tensorflow:Restoring parameters from ./my_model_variational.ckpt\n" + ] + } + ], + "source": [ + "# decode\n", + "with tf.Session() as sess:\n", + " saver.restore(sess, \"./my_model_variational.ckpt\")\n", + " outputs_val = outputs.eval(feed_dict={codings: codings_val})" + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n4oknattsvvnmIV933XUhr127NuRf/OIXGz0u6GsaPfHw2GOPDblchFwuBi5/0aWqqurEE08MeeDA\n+GNz2bJltW0eeeSRkFevXh3yn//855AnTZpU24cBPAB9jjIBIE2ZAJBmZlIobwT3zjvvhHzYYYeF\nfPnll9f20daDbhYuXNjh4yofuGVmAlF5Q8aqanzjxv/foYceGnI5H6mqqhoyZMhG97F8+fLaa23d\nQPeVV14JudG8p3//3vX/+r3raAHokZQJAGnKBIA0M5NC+Xvm5e+U77fffiGPGjWqw59x33331V5r\n6zvWrbfeusOfA31Jo1lkOUcpz9dzzjkn5EbzkXK9x/r160N+7bXXatuUM5Ayl8fVaGbS27gyASBN\nmQCQpkwASDMzKdx1110hlzOTHXfcscP7XLp0acg33HBD7T1t3Yfn+OOP7/DnQl9S3nerquqzyM02\n2yzkz3zmMyG3535Y5X3yZsyYUXtPeS+uUrkWrbfdh6sRVyYApCkTANKUCQBpygSANAP4NpQLlDZl\n8eDdd98d8vvvv9/hfRxyyCEd3gb6kpdeeqn2WjksL2/KWC4WbGvxcFXVB/0vvvhi7T3lfsubNm6/\n/fYht3Vz2N7AlQkAacoEgDRlAkCamUkHzZ49O+Rddtml9p4rr7wy5J///Ocd/pzyhnPl4iro69pa\nkFhV9VnEsmXLQn700UdDLh9+V1VV9eGHH4ZcPkCr0cOxSuXi529/+9sh97YHYTXS+/8EAHQ7ZQJA\nmjIBIK1fe36vugt0y4e2R/ndZXkDtrFjx4Y8fPjw2j7mz58fcvl33J6buu25554hP//8821u04P0\n/rvW0RE94nyeO3du7bV999035BUrVoRczlkazV3KdWH/+c9/Qi7XojXy8Y9/POS333475EGDBrW5\nj27UrvPZlQkAacoEgDRlAkCaMgEgzaLFwrXXXhvy2WefHfKCBQs6vM9N+SWH8kZxwMbtsMMOtdfO\nPffckC+77LKQFy5cuNHcSPkLNO35hZrJkyeHXC5ibAWuTABIUyYApCkTANJa74u7pDPPPDPk0aNH\nh7xkyZI297HbbruF/OCDD4Z82223tbmPVrjxGzRTowdMnXXWWSEPGzYs5AceeCDkRYsW1fax4447\nhlwuOGz0UK5169aFfNppp4XcnjlLb+MnFgBpygSANGUCQJqZSaG84dqpp56a3ufMmTM7vE2jh/QA\n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\nWRCAAwAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# plot the reconstructions\n", + "fig = plt.figure(figsize=(8, 2.5 * n_digits))\n", + "for iteration in range(n_digits):\n", + " plt.subplot(n_digits, 2, 1 + 2 * iteration)\n", + " plot_image(X_test[iteration])\n", + " plt.subplot(n_digits, 2, 2 + 2 * iteration)\n", + " plot_image(outputs_val[iteration])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Generate digits" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "INFO:tensorflow:Restoring parameters from ./my_model_variational.ckpt\n" + ] + } + ], + "source": [ + "n_rows = 6\n", + "n_cols = 10\n", + "n_digits = n_rows * n_cols\n", + "codings_rnd = np.random.normal(size=[n_digits, n_hidden3])\n", + "\n", + "with tf.Session() as sess:\n", + " saver.restore(sess, \"./my_model_variational.ckpt\")\n", + " outputs_val = outputs.eval(feed_dict={codings: codings_rnd})" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saving figure generated_digits_plot\n" + ] + }, + { + "data": { + "image/png": "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\nX4hYz549e2TS1syZM0lJSQnoGRT7p76+nrlz53Lw4EF5R5pMJhISEvi///s/aakPGzbMXxPHL3lj\n/qQElPzH/78+RBwS0booEHNUriREogZoBzouLo7Q0NCgPNDi3fm6aX2zIf+X3+OVhNvtpri4WMYz\nQHMnnT+a/n8N0TpI7G/RHaSrFVbfOHkAk6OUgFL8dOnKmM+VgHoeiisMJaAUCoVCEZRcsoAKPt+O\nQqFQKBQoAaVQKBSKIEUJKIVCoVAEJcFaqKsiwAqFQvE/jrKgFAqFQhGUKAGlUCgUiqBECSiFQqFQ\nBCVKQCkUCoUiKFECSqFQKBRBiRJQCoVCoQhKlIBSKBQKRVCiBJRCoVAoghIloBQKhUIRlCgBpVAo\nFIqgRAkohUKhUAQlSkApFAqFIihRAkqhUCgUQYkSUAqFQqEISpSAUigUCkVQogSUQqFQKIISJaAU\nCoVCEZQoAaVQKBSKoEQJKIVCoVAEJUpAKRQKhSIoUQJKoVAoFEGJElAKhUKhCEqUgFIoFApFUKIE\nlEKhUCiCEiWgFAqFQhGUKAGlUCgUiqDk/wGU+cCUakDTdAAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_multi_images(outputs_val.reshape(-1, 28, 28), n_rows, n_cols)\n", + "save_fig(\"generated_digits_plot\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Interpolate digits" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "INFO:tensorflow:Restoring parameters from ./my_model_variational.ckpt\n" + ] + }, + { + "data": { + "image/png": "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\nww9b/uyzzywfOnTIcp06dSzTDrlHh2roOaIrdOgqBLpjkg6Loo1unH43VaxY0bK/q5uuDqEznnX4\nmQ6l0bbQmdT+qivHjh2zrOee9ju6detmWcvWedXefAMCAAAgiE4jAAAAggptefry5cuWJ06cmPDn\nzkVvLeuC3uXKlbOst5N1AWgtC5w8eTLyvFlZWZZnzpxpWUud6ToTVEsAn376acK/qVq1auTfb7/9\ntuW4BVCzw589vWDBAsu//PKL5YMHD1rWkkHcAuCInid6LL/99lvL586dS/hYnSXaokWLyO+YtZs7\n9LjWqlXLspZHdaanlrNZBSJ5/BUZtPS8Y8cOy1u3brV84sQJy4MGDbJcunTp3HiLaUOvLzqzefjw\n4ZG/0+FLOvxMnT171rKWt7Xf8PPPP0ces3DhQsv6XaXPpddQ/RvK0wAAAEgZdBoBAAAQVKjK03qb\nX2/76sKa/n6cus9qr169Ej6vlt301rDuy3r06NHIY3SW4qlTpyzrrNJ0LU/rMdAyps6Y7t27d+Qx\nWq6+0dvw+rnwy6Pbtm2zvH//fstaLvVL2vh/fllNF0d/7bXXLGsba9uVKlXKcsOGDS37QwC0XKpD\nE5jJnjx6LLX0vHfvXss6k7dYsWKRxzNsIHnihj3p/uANGjSwHDdLF9kTt2GDtsMbb7wR+Z1+/uOu\nQ9oW+hr6faILdTsXvfbpsB5dXFzPz/zYX5yrLgAAAILoNAIAACCoUJWndR9pnW2rM6b92WWvvPKK\n5eLFiyd8Xr0FXLt2bcu7du2y7JdrtKQdd2s6negxWL58ueWffvrJcqVKlSzrvrjORdtAnyuuHKN/\no+VwncnunHPfffedZZ0lrbPdtPwTV8pIl7KQ/v+PHDkS+Z0OKdi5c6dlLd907NjRsg4HuV7JRRfA\n1XNUS9XpcvyTSdtSF9bv169fwp/r+eGX1fzrH3JOh+noAs/6naLnkZ4TOvzG/z7jHLlGv4fjZiDr\ndctfseNGj6X+vWa/P6LfgbrxhK7mEfce8wp3GgEAABBEpxEAAABBhao8rbNf165da1lnX+qMTeei\nt/zPnDljWUuSus/kxo0bLX/zzTeWT58+HXneq1evWtYynr+ncrrQEvGoUaMsazlFS5R+aUWPZ9zP\n9TV0T+tZs2ZZ1sW8nYu2uZZF69atm/B96edF2zJdSj+62LDuV+xctHypZZOuXbtanjt3rmUt+cTt\n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\nSUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAo0AAAB9CAYAAADHoFl9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAFklJREFUeJzt3XmwjvX/x/F3e5FSZM2WSJZkK20yiZoWKrQNZZoQozLT\nNowZmjRt32ow/cGMlGYqlT1FESpMOpbsa+IQsku2tt9fv7fX5+pcPudwjrPcz8dfr6/7Pte5uz7n\nuu7P93p/ltP+/fdfAwAAAI7n9ML+AAAAACj66DQCAAAgik4jAAAAoug0AgAAIIpOIwAAAKLoNAIA\nACCKTiMAAACi6DQCAAAgik4jAAAAos4spN/LNjQF67R8Og7tVLDyo51oo4JFGxV9tFHRRxsVfblq\nI540AgAAIIpOIwAAAKLoNAIAACCKTiMAAACi6DQCAAAgqrBmTxeIf/89NrnqtNPyPllLf/7QoUOe\nzzzz2Gn6888/PZ977rmezzjjjDz/PgAAgOKCJ40AAACIotMIAACAqGJTns5N6Vn/Pbel6qNHj3o+\nfPiw55UrV3qePn2654ULF3q+//77PXfq1Ck4LuXqgqNt+/fff3v+559/POswAn2/DikwC4ceIP/o\nOde22LJli+cxY8Z43rlzp+dkGw0YMCD1NeQPba8jR454zs7O9lyqVCnPF198cfDz2i4nMjQIQPHA\nk0YAAABE0WkEAABAFJ1GAAAARBWbAV15HSeT2/efddZZnnfv3u15xIgRnufPn++5QYMGnlu0aHHC\nnw/Hp2OszMJxVnPmzPE8ePBgz8uWLcvx/eeff77nxo0bB8e99957PXft2tXzeeeddyIfO6Pp+NLt\n27d7HjRokOfJkyd73rZtm+fTTz/2/1/LlCkTHFf/d9++fT2fc845J/eBM5yONdV73Isvvuh55syZ\nnlu3bu1Zrzszs2bNmnlmnHDB02tN21HPfXJcPd9RBU+/t3SMvbaX3uuKYxvxpBEAAABRdBoBAAAQ\nlfF1hL/++suzlj2/++47z/v27fNctWpVz/poWR9Fm4WPoJE7+mj/4MGDwWs//vij5+eee87zmjVr\nPOuj/bPPPtuzlqq1DGdm9tNPP3nWkvRDDz3kmXJbzrQsZhaey8cff9zz6tWrPet1ceGFF+b478my\n8/fff++5Z8+eqe9DnN6ndHiADsdZvny557p163pu376953r16gXHLQ5lteJIr7G5c+d67tGjh+e9\n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\n/NKz/l2Ype8xraVq/Vw64zQTy6N6vlavXh28pjPcdW/cPn36eO7Xr59nPZfadjo0wCz8e2ncuLFn\n3fMVuaPtp6U4nY174403ep48ebJnXXlA329m1rZtW89pi+zjGL2n7N27N3itdevWnhs1auQ5bRUH\n3bddz31yg4LkxhaZ7MiRI55nzZrlWe81ej9LlvPz696fvIdpX0P7FGnfQYWBqxsAAABRdBoBAAAQ\nRacRAAAAUSVqTKNu9q3/ruMGdEyUWbhbiO7wosuHfPLJJ57nzJnjWXeaSY4f0TEPuuq7bkCfSXRM\nxm233eZZx5HqEge6ZItZOM5H2/aXX37x/Oabb3rW9tMN4o83rkdX9k8bT6KfMVPGNOr51h0ndMyP\nWbh8kY5j1KWUdKkKpeO1qlevHrz23Xffea5YsWKO7yvscT7Fhf79a7vWqlXLsy770aFDB8+688iy\nZcuC47Zq1cozy+/E6X1Px7GZheNF9bpIWxJOl6TSMdu6LI/Zf7+jMo2es/Xr13sePHiwZ91tTJcE\ny897vX4OXUrHzGzp0qWe9btGd6ApbNxpAQAAEEWnEQAAAFHFvjyttESiO39oSWzx4sXBz+hyB9nZ\n2Z5nzpzpWcvQWt7RR9bJqfMtWrTwPGjQIM9aMsiU8qZZWC7WEoouZTBw4EDPzzzzTPDzWprRNhs+\nfLjnGTNmeNZlebT9k+XRUqVKedbytJbo9uzZ41nLF/rZS1pbpi3NoqVmXZbIzOyxxx7z3LdvX8+6\n5FTa79Dzlyw1awln3rx5nl955RXPWsbDMcmSpJZFL7jgAs96Xej51+E0jzzyiGe9V5qF15veC0va\ndXEy9O9dh0Ill2tr2LCh57RhF3pe9TtJ71XJZcu03JnpdKk2vY/p37V+Z9WoUeOkfp+2vX7/vfvu\nu8H7dKk+3b2uWbNmngv7muJJIwAAAKLoNAIAACCq2D+v1sf3PXv29Ky7gOgj+2+++Sb4eX2Er6vE\naxlH6SN+3V3m2WefDd7Xpk0bz1r21DJrSaezjseOHes5bYcc3R0mScsGvXv39qwza9NK0rqrQoMG\nDYLj6sxD3TxeyxH6t5A2+7SwSwb5TctnOmxg2rRpnmvWrBn8TNWqVT1v377ds5Zc0srQOgRk1KhR\nwXG//fZbzzozV2fF6zWW6TOp9brTe5pZ2K46NCNtVQE9lu4AlJz1qfc7LXvjGD3H+vee/HtN26Uq\n7T0LFizwrKXPKlWqBD+TtnJBJtJVGPRvXNtl6NChnps0aRL8vA4zS7vfaBvpkKoHHnjAc1ZWVvAz\nek2OGDEix38vbJl9dwUAAECu0GkEAABAVLEvTystPY4cOdJzv379PGuJxSy9xKgzY3Vm5ksvveS5\nS5cunpML2uoj67yWLktK2VPLutOnT/esZWQtXT7//POedaFoM7O5c+d63rdvn2ct+Wgb6GLg3bt3\n96xDCszCdtbPpcdNzoz/f9pOyZJScWw3nWk7depUzx999JFnnXWoC30n3zd58uQcf0bLZ2nnW99v\nFi5+XKdOHc8667Ru3br/+e/JJHr+9HwtX748eJ8uHqzlSh1qoOXlcePGedZyWfI60vKbDlPAMXpP\n0DbShabNwlJo6dKlPet3il4jupC+tmn//v2D42bS0Kic6PnXv1H9W9b7lq6g0rFjx+BYTz75pGft\nd+h1OGnSJM9vv/225927d+f4mczMOnfu7Llly5aei9KQm6LzSQAAAFBk0WkEAABAVIkqT+vj95tv\nvtmzlkaTpYCNGzd61lKlLrCqC9zqzN+CemR8vNJmcSpd6/nUhdd1D1udFb1p06Y8HzdtEXV9tK/l\n5WSb6TlMm7WY20WoSxI9ZzrDXGfjJstdK1euzPE1LXvr6gNp++cmZ2VrGz/99NOedb/kktwWJ0MX\nQzcLy2Q6U1Rng+o9Tu+P9erV86z78pqF+yUX9ftSYdHzokOekve9YcOGedZhNrrI/nvvvef5l19+\n8azt0qlTp9Tfn+n0O2TIkCGe9Vzq0A79zjIzmz9/vue07wcdfqMztPUeqP0UM7O33nrLc9qwqMLG\nnRYAAABRdBoBAAAQdVpuFhItAIXySzNIftUhTqqd0mZ0vvPOO55nz57tWWdb64LcZmYPPfSQ5/r1\n63tOKz0XVCkm7Xo5wd+XHx+yQK4lLa0cbz9bpSUfbXstaet50pJNuXLlPCdXIkjb4/sUlduKbBul\nOd5M9HXr1nnWoTpahtZF7rVcp4sS69AAs/T9xU+RYtdGeh2NHj06eO2NN97wrEMI9DqqVKmSZ92X\nWGe4F7H92ItsG+k9XTclGDBggOcpU6YEP6MreOj3lh5LrwndfODRRx/1rBsnmIWz5QtBrtqIJ40A\nAACIotMIAACAKMrTJVORKE8jqsiWbOBoo6KvWLeRDt0xCxeYXrJkiWcdatCjRw/PtWvX9lxUZ9xa\nMWwjHeahe7abhXuv69COrVu3etaZ7zqc43ireRQyytMAAADIH3QaAQAAEEWnEQAAAFGMaSyZGNNY\nPBS7cT4ZiDYq+mijoo82KvoY0wgAAID8QacRAAAAUXQaAQAAEEWnEQAAAFF0GgEAABBFpxEAAABR\ndBoBAAAQRacRAAAAUYW1uDcAAACKEZ40AgAAIIpOIwAAAKLoNAIAACCKTiMAAACi6DQCAAAgik4j\nAAAAoug0AgAAIIpOIwAAAKLoNAIAACCKTiMAAACi6DQCAAAgik4jAAAAoug0AgAAIIpOIwAAAKLo\nNAIAACCKTiMAAACi6DQCAAAgik4jAAAAoug0AgAAIIpOIwAAAKLoNAIAACCKTiMAAACi6DQCAAAg\nik4jAAAAoug0AgAAIIpOIwAAAKL+Dw7VXfPWdetKAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n165dLdOu5+lwgPnz51s+ceKE9zq9Run32rp1a8s6REqHxenucdGZ8npN1HNy1KhRlvO6vXjSCAAA\ngCA6jQAAAAgqUOVpfbT8/fffW96/f7/l6KPdLl26WNbZSlkpSSudLe2ccz/++KNlnXX49ddfW+7T\np49lZlL7tHzjnF8O0LK+Lkq8detWy/q3oG0ZXZRVy9vRmfW4eHqeablt3bp1lnUhWy3/6Cx2JJae\nR7qSg37/O3futKwlzuxeExFPr0/Fixf3fqareOis2TvvvNPy6dOnLes5tWzZMstHjx71jrtgwQLL\nnTp1shzd8CCV6T1g6tSplqOrbmhJ+sEHH7Q8aNAgyzqrXY/boEEDy/369fOOq8MLtF11+JvO0M4L\nXAUAAAAQRKcRAAAAQQWqJqqPgIcPH25ZH+XrbGnnnOvbt6/l6IzdzOhjap31Nn369Nj36Exe3QdZ\nPy/lad8ff/zh/bfuX6wzznQfT/0OtQynpe7oXp+LFi2yrLPaWrVqZZmyXPbpebJq1SrLWlrREo/O\nBtX93Z1jv/ZE0vNCF7bX802HfMycOdNyhw4dLEdLmsx4zx69JmnZ2Tnnbr75ZssdO3a0XKJECct6\nTdL2mjVrlmWdfeucf7+JztjGObpygF63ihYt6r2uZ8+elocOHWo5bgF8vR6mp6dbrlGjhndcnT2t\nbax9GL1u5gXuhgAAAAii0wgAAICgAlUT/eWXXyxr2VEf8+qsMeecq1SpkuW4Eos+WtaygpZ0Vq5c\n6b3n1KlTlrUsoOXU6IysVKTfgc5+fv75573XaVlfZ9dqubNJkyaWdajBkiVLLB8/ftw7ru5dPXr0\naMu6hyuzC7NG21KHEKxevdrySy+9ZFn3WdXZu1qqds650qVLW2aoQOIcPHjQsp5Hus+7zqTWPcTb\ntm3rHYshBGF6fug94aabbvJep7OpdcOBuL99fb0u2F6+fHnvdToDV89PPb9ScZiBfi96fcrIyLDc\nsmVL7z1DhgyxrG2Ule9Ph1Fp2TlKhx0k03ACrsAAAAAIotMIAACAoHxfntbHtg899FCm/66Pj+++\n+27v/frIX0sG+shaHyGvXbvW8siRIy3PmzfPO66WQbW8mZaWlun/Di1dpFKJQBdQfeSRRyxred85\n58qUKWO5TZs2lnWhb93XWxdW1fLNwoULveNqmWbTpk2WtTSRlSEM8IdejBs3zrK2lw4P0b95/b61\n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\nORIASqOWeQAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAo0AAAB9CAYAAADHoFl9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAFfZJREFUeJzt3XmwjmX8x/FLRUJROHZHdrJmLWTIVvRPyi5pGZlMo2Vi\nRo1JUxgjzBg1atAYIxM1qsFkm5EiYbJmiew7RWRL/f74/fr63NfvuV3ncJbnOc/79dfHOedZ3Ndz\n38819/daCv37778OAAAAuJHb8vsNAAAAIPnRaQQAAEAQnUYAAAAE0WkEAABAEJ1GAAAABNFpBAAA\nQBCdRgAAAATRaQQAAEAQnUYAAAAE3ZFPr8s2NLmrUA49D+2Uu3KinWij3EUbJT/aKPnRRskvS23E\nnUYAAAAE0WkEAABAUH6VpwEAAAq8f/+9XlkvVCinRo/lD+40AgAAIIhOIwAAAIIoTwMAgLR0M6Vj\nfYzmY8eOWS5cuLDlokWLWi5evLjl225Lvft2qfeOAQAAkOfoNAIAACCI8nQMveWclZ+n4m3mVKVt\n8M8//1i+evWq5ZMnT1q+/fbbLZcsWTLyXFoqQO64du2a5T179lh+//33LR84cMDygw8+GHn80KFD\nLZcuXdqy35b/SfXZiQDyzs1cL/SadvHiRcunTp2yvGzZMst//fWX5eHDh1suUaJEtl87v9HTAQAA\nQBCdRgAAAATRaQQAAEBQ2o1p9MckXrlyxfKOHTssT5o0yfLGjRst6/i4zMxMyw8//HDkeR977DHL\nderUsVykSJGbedtpT8crbtu2zfJrr71mWdvp3LlzlnW8aalSpSLPO3HiRMsDBgywrO2MrNFzS8f5\nrF+/3vIHH3xgedGiRZbvvPPOhI91zrlnnnnGctWqVS0zdjHnaNsdOnTIsp5rrVq1suyfR7QF0skd\nd1zvOun3y5dffml5xYoVlvv27WtZl99JRdxpBAAAQBCdRgAAAAQViltCJpfly4s6Fy1HOxctxYwc\nOdKy3lrWxxQrVixh9m85V6pUyfKIESMst2vXzrKW5HJYTtWKkqaddPmCF154wfLx48ct62c5bgkk\n/+cZGRmW161bZ7lixYrZfMc3JSfaKd/aSJc7cs65S5cuWdb2WrJkieUTJ05Y1mUodHiHDhNwzrny\n5ctb1nMmj0qiKd1GWaVt8cQTT1jWIR/Tpk2z3KtXr8jj83k4R4FqIz2vLly4YHn//v2Wx40bZ3nt\n2rWWtR30+8m56DIxOmRqyJAhllu3bm1ZzzV93ptcXq5AtZF+12zYsMFy7969Leuyb4MGDbKsQ9+0\nzJ0EstRG3GkEAABAEJ1GAAAABCXVvdHcoreS//7778jvdINx3ZVCb8eXKVPGct26dS3r7Wctc/u/\nGz16tOWPP/444XOxo0y0nf7888/I72bMmGFZy6DlypWz3LlzZ8s6e/2rr76yvHDhwsjzanlbX2PU\nqFGWmRl6XdwMaeecW758uWU9ztWqVbM8bNiwhD8vXLiwZf9c0ONPW+QcLVfqZ1+H5uiOFXqu+NdR\nVhu4ef4QMb32TZkyxfL06dMt6/eWtqPyzyN9ne3bt1tevXq15RdffNHy448/bll3adJz1bn0PCf1\nWOp3vQ6/0SFWer7oz5OsPJ0l9FQAAAAQRKcRAAAAQal3b/QW+TM+V61aZfno0aOW7777bss647lG\njRqWdTablm6ci5ZQ9+zZY1lLpTVr1rTMot9RfjtVqVLFcteuXS3379/fcseOHS3r8Wzfvr3l77//\nPvK8Oqxgy5Ytt/CO04OWZXbv3h35nZY4q1evblkX565QoYJlLc3cqMSVjuWvvKBlsqVLl1quX7++\n5Z49e1pu27atZdok5/jl6dOnT1teuXKl5fPnz1vW4QBx+a677oo8r67wcfnyZct6rmq7+rOvE/1N\nutLvJ509rUMFdHjA77//bvnw4cOW9dg7lxrDPLjTCAAAgCA6jQAAAAhKi/K03v7XErRzzn300UeW\nz5w5Y/nee++1/McffyR83oYNG1rWcrRz0UVx9fXjZlTpjLR0vf2v/2+/tFK7dm3LWqpu06aN5biF\nn/WY657UzkXbpmzZsjfzttOKfmb9Ur/O6NRSpp5LWrJhVnTe08/7nDlzLOse0926dbPcokULy1re\n9IeP4Ob5GxlMnTrVss5y1mN+zz33WNYSZ5cuXSzrfsfOOVe5cmXLZ8+eTfi8Wl7VIVq0d9SpU6cs\n66x2Lfvr+aL9Dt3sYPDgwZHnLV68uOVkvSZypxEAAABBdBoBAAAQlBbl6atXr1oeO3Zs5HdHjhyx\nrKUbne2kZWstzzVr1sxykyZNIs+rs950EeRatWolfF9aWo0r4aUTf1/uhx56yHLp0qUtx83w05LP\nvHnzLOseu85Fj6++Bq6LG17hL2ifmZlpWRcD1hmB+bTXPf6PHn8tseksaS1P60xezbryA7JP28Ff\neUNX2NCFvvWa2KpVK8u6d3SnTp0s+yty6PdKXOlZh+/o32vZ2l/YPRUXqM4u/a52zrnx48db1mE5\neix0pQj93tfFwPft2xd53nr16llO1pnU3GkEAABAEJ1GAAAABBXY+8px+xjrrX/n/v9t50R0lnSv\nXr0saznOL7vpbF9dBPzChQsJX4OZpFF+yUOPZ9wMdG2DgwcPWl6wYEHs69x3332WdRFw2uA6PRY6\ny19najoXXTFAZ+PqeaL7uGuJjOOd91q3bm1Zy4+637TO9KxTp45lhnLcGi0JT5s2LfI7/b7Qa5rO\nrG3ZsqVlbRctad7MOaWrVuhr6/X4RntaF6TzWP9fuiC3c87NnTs34WN0ZY8xY8ZY1nbZtWuX5XXr\n1kUeX7VqVcs6Qz6ZcKcRAAAAQXQaAQAAEESnEQAAAEEFdkyjjhkZNWqU5bjdXZyLjtvo3r275REj\nRljOyMiwrOO7/DGNOrZDd8RQLD8Szx8bo8dax4XqEjonTpywrOOEdFcFX8eOHS2zI0yYLvvRrl27\nyO907OLnn39uefbs2ZZ1SRAdU+ePk0Lu0zGleu3bvHmzZV16rFKlSpaTdTmQZKbXe13G7ZNPPon8\nnY7T1uugHvMNGzYk/PsePXpY9pdF8nfZSvS8WRlb7/+8II1jVNqH0OuZc9EddfTc6dOnj2Ud96vz\nKnSZvwMHDkSeV/snyTrmmys1AAAAgug0AgAAIKjAlqcvXbpkefHixZb9krDeWn722WctT5o0yXJW\nNhH3N3TXJSx+/fXXhM+lJTlK1Tem7aR5y5YtlidMmGB51apVlnUTeX8HmX79+lnWEjjC/GWRqlWr\nZvmpp56yPH/+fMs//vij5aZNm1q+1aVCkDV6XdLylx7/PXv2WNbdrHQnJtoo+/Qav3TpUstaurzR\nY7SkvWzZMst6rdPvugceeCDyXNWrV7fcuHFjy7p7k34/6ZIv6bhLmX5vzJgxI/I7XaqvVKlSlhs0\naJDw51rOXrFihWV/R5iKFStaHjRokGV/h7T8xJ1GAAAABNFpBAAAQFCBKk/rrfzdu3db1hlJfknt\n6aeftjxlyhTLfhkzxL9lr7MOFy1aZLlcuXKWdacZZo9mnQ49+Prrry2vWbPGss6q1tJbo0aNIs/V\noUMHy+lSdskt+hnWUvWjjz5q+bPPPrN86NAhy7Vq1bJMO+QeLbnpOaKzOHUVAt0xSUtntFH26fdT\n+fLlLfs7f+jqEDrjWUuUOpRG20JnUvszc48fP25Zz71NmzZZ7tq1q2UtW6dLe2sbrV+/3rJfRtbj\noaX+tm3bWtbroR7juNUJnHNu8uTJlps3b25Zh/Lkd1vQUwEAAEAQnUYAAAAEFdjy9KeffprwbypX\nrhz59zvvvGM5bvHTrPBnTy9YsMDyL7/8YvngwYOWtVwQtwA4/peWXfR4fvvtt5bPnz+f8LE6S7RZ\ns2aR3zFrN3foca1Ro4ZlLY/qTE8tZyfTTMFU56/KoKXnHTt2WN66davlkydPWh44cKDlkiVL5sZb\nTBt6fdGZzcOGDYv8nQ5h0hKlOnfunGUtb+twgp9//jnymIULF1rW7yt9Lr2G6t+ky7XxypUrlidO\nnJjw585F+wq6oHeZMmUs63eWfr9rG506dSryvMeOHbM8c+ZMyzqULb9X+eBOIwAAAILoNAIAACCo\nQJWndVatljB1xnSvXr0ij9FydXZvwWvpxy+Nbtu2zfL+/fsta6nUL2njOr+spgukv/7665a1nbX9\nSpQoYbl+/fqW/WEAWi7VkgOz2XOOHkstPe/du9eyzuQtUqRI5PHpUhrLC3GlMd0fvF69epbjZuki\na+I2bdB2ePPNNyO/089/3HVI20JfQ79TdKFu56LXPh3Wo4uL6/mZLvuL6/HTkr4umu4fi06dOlnu\n2bNnwufV8rT2D1q3bm356NGjkcdoe58+fdqy9m0oTwMAACDp0WkEAABAUMqXp/XW8vLlyy3/9NNP\nlitUqGBZ98R1LnrbWZ8rrhSjf6O3jHWmk3POfffdd5Z1lrTOdNPbzHFljHQqCekxOHLkSOR3Oqxg\n586dlvV2fvv27S1ryeBGJRddALdo0aKWtVSdTm2QU7QtdXH9vn37Jvy5niN+Wc0vV+Pm6VAdXeBZ\nS2l6Huk5oSU2/blznCNKS8RxM5D1uuWv2pHdY6l/r9mf7a7fg7qotK7oEfceCzLdR1pXU9EZ0/6x\nfPXVVy3758J/9LumZs2alnft2mXZv7bpeRg37CC/pcenAgAAALeETiMAAACCUr48rSXikSNHWtZS\nipYn/VvJ165dS/i8+nN9Dd3TetasWZZ1MW/nnDt79qxlvU1du3bthO9Lb0trCSmdyj662LDuV+xc\ntHypZZMuXbpYnjt3rmUt+cTtsZvo3/9p0KCBZX+/coRpyUdLMDozV2eua7lMy9bORWea0hY5RxdU\nf/vtty3rORW3GHibNm1y982lGC0f6nePfq7Lli1rWb+Hcusa7z+vllt1ZrAOB8nMzMz195VsdHWT\ntWvXWtbrk67G4Vz0+1q/63XIme4hvnHjRsvffPON5TNnzkSeV/sdOkQrma573GkEAABAEJ1GAAAA\nBNFpBAAAQFDyFMqzQaei64rqhw8ftqxjAHQFdh3H49OxVGvWrLE8evTohK+nK+nrGC6fvqaOldOx\nWjpOL13GkjgXHf/z8ssvW9axVM5Fx3/26NHD8vTp0y3ruBM9njpmR5c8cs65rVu3Wl6/fr3ljIwM\ny7pURTq1TXbFLRGhuyDpmB89R/WxFy9ejDyvjg3S9qMtsk/HtZUpU8by/fffb1nHA+vfb9++3TJj\nGqN0jNvKlSst6/Wlf//+lqtUqZLr70nbzjnn3n33XcvHjh2z3LRpU8u6tEy6nF/6na7tqP9//blz\nzo0fP95yy5YtLZcrV86yjo/U5QB1Jyaffs9169bNcjLtzsOdRgAAAATRaQQAAEBQypendakbLX3p\n5uwjRoywfKMV2NetW2dZV3zXKfn62vpc/i4WlSpVsqw7LAwaNCjh+02XUoBz0WOuK/Dr8fc98sgj\nlidMmGC5WLFilrVtdOkCLdP4S+ysWLHCspaStG3085NMSx/kN3+Xgrjlq/Q80c+5lly0hK0lGuei\nw0b0ufJi2ZJU57fR6dOnLVetWtWy7lih9Dzwdy5BYrq8yg8//GBZr09vvPGG5ZwsPWp7L168OPK7\nZcuWWdZzdejQoZb1epoutLysJeElS5ZY9ofM6FAm3eElbrmluB1d/KV8BgwYYHnw4MGWk2lXLO40\nAgAAIIhOIwAAAIJSstam5UYtaeot3Dp16iR8rM54ds65Dz/80PLUqVMtnzx50rKWFbR01qpVK8ta\ngnYuOmO7UaNGlnV2WtzOL/p6mp0rGJvI79y50/KcOXMs684t/gbxlStXtrx3717LWgLQttUyge5k\noavx++9F20BX+dfPm5aSCnJJNO4zqKsE6E5JzsXvgqTHSc8fLc3oMdbhIM5FZyE2bNjQcosWLRK+\nBuLpcda20DbWv9m3b59lbS+Od5Rel/VYbtu2zbLOWH7uuecs6+oMzmX/2GrpU3d60bKzc9ESq85+\nT9ZZunlFh7lMmzbN8ksvvWR59erVkcecO3fOsn7v+LOs/6Pf9XXr1rWsQ62cc65du3aWdahAMp1v\nqd8DAQAAQK6j0wgAAICglCxP6+3448ePW9ZFgLWEOWTIkIQ/dy66sKc/Q+o/WirVBVpfeeUVyxUr\nVow8Jq48pz+PWwxZFYRytHPR2Xrz58+3rLM59Xhoedm56Ew2XXhdywHa/no8ddiCv+Ctvi9twyZN\nmlhOl1nuesz0uB46dMjy5s2bLfvn0pkzZyz/9ttvlrVsrSVRXfRe/0ZnJjrn3KZNmywPHz7csg77\nYGZvYv515eDBg5b1s6znmy4+rG0/cOBAywXlupRT9Lpevnx5yzrzX691EydOtPzee+9FnstfPSAR\nvY5NmTLF8tixYy3711Atg2sZ1p/Bm850wfvZs2dbXrRoUeTv5s2bZ1mHz2jZWjfvmDRpkuXOnTtb\n9ts6FYYHcOYDAAAgiE4jAAAAggr5s3PzyC29qJbOJk+ebHnMmDGW/ZmdcXRWk5a4+vTpY3nUqFGW\n9fZ13Ozn3JTF18mpN5NjHw4tk33xxReWhw0bZlnLYn75S2/bx5X+4xZ+rl27tmVtP+ece/LJJy3r\nLEJdbDoXF/TOiXbKsTbSa8Hly5cta4ly9+7dlnXhYueiexNr6VrbqHTp0pZ1trwOLdDX9h+je742\nb97cclZKejcpqdoou3S2u3POzZo1y7IuSqzlTj1X9fzQmZ1Jtsh9UrWRrryh1x4dgqHXtw4dOkQe\nH7fwt55TM2fOtKyLiet3o79Q99y5cy13797dch59dyVVG2X7hb1+kp4jcZsaaBunyKobWXpj3GkE\nAABAEJ1GAAAABKVkeVpLLjobcOTIkZZ1H2Hdh1pnLjnn3PPPP285IyPDctx+ubklbjFl/7VTtTyt\ntP0OHz5sWfeF1nKlc9H2iJvNrLMWtbys2d/DMz+GGIikLdlo+UWzfjb9hWz1+MU9XulqBdqmfhvp\nv/OhzJO0bZQV/rHXmejjxo2zrOdev379LOswHR3akWQltqRqIz1HdP/n3r17W9brm/8drMc2btOH\nuOOvM3aXLl0a+V3jxo2Dj89FSdVGSIjyNAAAAHIGnUYAAAAEpWR5OvZJs3D7Pk0kdXkahpJN8itQ\nbaRDQ3Qh4hMnTljOzMy0rKsQJPGC3knbRvqdpBtR6IocWsJ2LjrLWttLn0sX6n7rrbcs6wLsSbbg\nfdK2EQzlaQAAAOQMOo0AAAAIotMIAACAoAI1phGGMY2pgXE+yY82Sn60UfKjjZIfYxoBAACQM+g0\nAgAAIIhOIwAAAILoNAIAACCITiMAAACC6DQCAAAgiE4jAAAAgug0AgAAICi/FvcGAABACuFOIwAA\nAILoNAIAACCITiMAAACC6DQCAAAgiE4jAAAAgug0AgAAIIhOIwAAAILoNAIAACCITiMAAACC6DQC\nAAAgiE4jAAAAgug0AgAAIIhOIwAAAILoNAIAACCITiMAAACC6DQCAAAgiE4jAAAAgug0AgAAIIhO\nIwAAAILoNAIAACCITiMAAACC6DQCAAAgiE4jAAAAgug0AgAAIIhOIwAAAILoNAIAACDofwDMzy/w\npqgG7QAAAABJRU5ErkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "n_iterations = 3\n", + "n_digits = 6\n", + "codings_rnd = np.random.normal(size=[n_digits, n_hidden3])\n", + "\n", + "with tf.Session() as sess:\n", + " saver.restore(sess, \"./my_model_variational.ckpt\")\n", + " target_codings = np.roll(codings_rnd, -1, axis=0)\n", + " for iteration in range(n_iterations + 1):\n", + " codings_interpolate = codings_rnd + (target_codings - codings_rnd) * iteration / n_iterations\n", + " outputs_val = outputs.eval(feed_dict={codings: codings_interpolate})\n", + " plt.figure(figsize=(11, 1.5*n_iterations))\n", + " for digit_index in range(n_digits):\n", + " plt.subplot(1, n_digits, digit_index + 1)\n", + " plot_image(outputs_val[digit_index])\n", + " plt.show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notes/tf_rnn.ipynb b/notes/tf_rnn.ipynb new file mode 100644 index 0000000..0ad0437 --- /dev/null +++ b/notes/tf_rnn.ipynb @@ -0,0 +1,2568 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Tensorflow for RNN" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# load library\n", + "import os\n", + "\n", + "import numpy as np\n", + "np.random.seed(42)\n", + "\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline\n", + "plt.rcParams[\"axes.labelsize\"] = 14\n", + "plt.rcParams[\"xtick.labelsize\"] = 12\n", + "plt.rcParams[\"ytick.labelsize\"] = 12\n", + "\n", + "import tensorflow as tf\n", + "\n", + "PROJECT_ROOT_DIR = \".\"\n", + "ID = \"rnn\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# save figures\n", + "def save_fig(fig_id, tight_layout=True):\n", + " path = os.path.join(PROJECT_ROOT_DIR, \"images\", ID, fig_id + \".png\")\n", + " print(\"Saving figure\", fig_id)\n", + " if tight_layout:\n", + " plt.tight_layout()\n", + " plt.savefig(path, format=\"png\", dpi=300)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Basic RNNs" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1 Manual RNN" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# unroll RNN manually\n", + "n_inputs = 3\n", + "n_units = 5\n", + "\n", + "x0 = tf.placeholder(tf.float32, [None, n_inputs])\n", + "x1 = tf.placeholder(tf.float32, [None, n_inputs])\n", + "\n", + "Wx = tf.Variable(tf.random_normal([n_inputs, n_units], dtype=tf.float32), name=\"Wx\")\n", + "Wh = tf.Variable(tf.random_normal([n_units, n_units], dtype=tf.float32), name=\"Wh\")\n", + "b = tf.Variable(tf.zeros([n_units,], dtype=tf.float32), name=\"b\")\n", + "\n", + "h0 = tf.tanh(tf.matmul(x0, Wx) + b)\n", + "h1 = tf.tanh(tf.matmul(x1, Wx) + tf.matmul(h0, Wh) + b)\n", + "\n", + "init = tf.global_variables_initializer()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "x0_batch = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 0, 1]]) # t = 0\n", + "x1_batch = np.array([[9, 8, 7], [0, 0, 0], [6, 5, 4], [3, 2, 1]]) # t = 1\n", + "\n", + "with tf.Session() as sess:\n", + " sess.run(init)\n", + " h0_val, h1_val = sess.run([h0, h1], feed_dict={x0: x0_batch, x1: x1_batch})" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[-0.33335388 -0.99984092 0.96257252 0.99972427 0.34358242]\n", + " [-0.34939748 -1. -0.6466651 1. -0.86954355]\n", + " [-0.36523882 -1. -0.9982453 1. -0.9952535 ]\n", + " [ 0.99999756 -1. -1. 0.99948496 -1. ]]\n" + ] + } + ], + "source": [ + "print(h0_val)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 0.914249 -1. -0.99999714 1. -0.9999699 ]\n", + " [ 0.91388243 0.82330334 0.99997503 -0.54982889 0.68797135]\n", + " [ 0.96552432 -1. -0.87868202 1. -0.99206823]\n", + " [ 0.98695272 -0.99991322 0.59633946 0.99998528 -0.40242517]]\n" + ] + } + ], + "source": [ + "print(h1_val)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Using ```rnn()```" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# static unroll RNN\n", + "tf.reset_default_graph()\n", + "\n", + "batch_size = 4\n", + "\n", + "x0 = tf.placeholder(tf.float32, [None, n_inputs])\n", + "x1 = tf.placeholder(tf.float32, [None, n_inputs])\n", + "\n", + "cell = tf.contrib.rnn.BasicRNNCell(num_units=n_units)\n", + "init_state = cell.zero_state(batch_size, dtype=tf.float32)\n", + "outputs, states = tf.contrib.rnn.static_rnn(cell, [x0, x1], initial_state=init_state)\n", + "\n", + "h0, h1 = outputs\n", + "\n", + "init = tf.global_variables_initializer()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "x0_batch = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 0, 1]]) # t = 0\n", + "x1_batch = np.array([[9, 8, 7], [0, 0, 0], [6, 5, 4], [3, 2, 1]]) # t = 1\n", + "\n", + "with tf.Session() as sess:\n", + " sess.run(init)\n", + " h0_val, h1_val = sess.run([h0, h1], feed_dict={x0: x0_batch, x1: x1_batch})" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[-0.84075469 -0.24504103 -0.47801617 -0.81902725 0.27693051]\n", + " [-0.88173866 -0.97021145 -0.63182706 -0.99945551 0.99449092]\n", + " [-0.91267502 -0.99924624 -0.74804145 -0.99999863 0.999973 ]\n", + " [ 0.99996418 -0.99994028 0.99749142 -0.99956077 0.99995661]]\n" + ] + } + ], + "source": [ + "print(h0_val)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 0.74716586 -0.99994993 0.2154983 -0.99999934 0.99999976]\n", + " [ 0.17931944 0.33916888 0.8354494 0.44775939 0.86307251]\n", + " [ 0.79777038 -0.99551833 0.86567175 -0.99961263 0.9999947 ]\n", + " [ 0.08692072 -0.97432131 0.91839492 -0.9430967 0.99913162]]\n" + ] + } + ], + "source": [ + "print(h1_val)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Packing sequences" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "tf.reset_default_graph()\n", + "\n", + "n_steps = 2\n", + "n_inputs = 3\n", + "n_units = 5\n", + "\n", + "x = tf.placeholder(tf.float32, [None, n_steps, n_inputs])\n", + "x_seq = tf.unstack(x, num=n_steps, axis=1)\n", + "\n", + "cell = tf.contrib.rnn.BasicRNNCell(num_units=n_units)\n", + "init_state = cell.zero_state(batch_size, dtype=tf.float32)\n", + "outputs, states = tf.contrib.rnn.static_rnn(cell, x_seq, initial_state=init_state)\n", + "\n", + "init = tf.global_variables_initializer()" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x_batch = np.array([\n", + " # t = 0 t = 1 \n", + " [[0, 1, 2], [9, 8, 7]], # instance 1\n", + " [[3, 4, 5], [0, 0, 0]], # instance 2\n", + " [[6, 7, 8], [6, 5, 4]], # instance 3\n", + " [[9, 0, 1], [3, 2, 1]], # instance 4\n", + " ])\n", + "\n", + "with tf.Session() as sess:\n", + " sess.run(init)\n", + " outputs_val = sess.run(outputs,feed_dict={x: x_batch})" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[-0.06258702 1. 0.90452164 -0.99995655 -0.99997294]\n", + " [-0.70032823 0.37023115 -0.01365535 0.36493999 -0.32459897]\n", + " [-0.62021768 0.99998254 0.39824897 -0.99698222 -0.99930936]\n", + " [ 0.31216088 0.99843973 -0.80233294 -0.98409343 -0.80607212]]\n" + ] + } + ], + "source": [ + "print(outputs_val[1])" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[array([[-0.11966424, 0.6925894 , 0.62398833, 0.17242405, -0.11511036],\n", + " [-0.07815791, 0.99931848, 0.86040169, -0.91863692, -0.96123236],\n", + " [-0.03637883, 0.99999869, 0.95251852, -0.99746436, -0.99901563],\n", + " [ 0.5348652 , 0.99992323, -0.999354 , -0.99938959, -0.98840386]], dtype=float32), array([[-0.06258702, 1. , 0.90452164, -0.99995655, -0.99997294],\n", + " [-0.70032823, 0.37023115, -0.01365535, 0.36493999, -0.32459897],\n", + " [-0.62021768, 0.99998254, 0.39824897, -0.99698222, -0.99930936],\n", + " [ 0.31216088, 0.99843973, -0.80233294, -0.98409343, -0.80607212]], dtype=float32)]\n" + ] + } + ], + "source": [ + "print(outputs_val)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Dyanmic unroll rnn" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# a clean code\n", + "tf.reset_default_graph()\n", + "\n", + "n_steps = 2\n", + "n_inputs = 3\n", + "n_units = 5\n", + "batch_size = 4\n", + "\n", + "x = tf.placeholder(tf.float32, [None, n_steps, n_inputs])\n", + "\n", + "cell = tf.contrib.rnn.BasicRNNCell(num_units=n_units)\n", + "outputs, states = tf.nn.dynamic_rnn(cell, x, dtype=tf.float32)\n", + "\n", + "init = tf.global_variables_initializer()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "x_batch = np.array([\n", + " # t = 0 t = 1 \n", + " [[0, 1, 2], [9, 8, 7]], # instance 1\n", + " [[3, 4, 5], [0, 0, 0]], # instance 2\n", + " [[6, 7, 8], [6, 5, 4]], # instance 3\n", + " [[9, 0, 1], [3, 2, 1]], # instance 4\n", + " ])\n", + "\n", + "with tf.Session() as sess:\n", + " sess.run(init)\n", + " outputs_val = sess.run(outputs,feed_dict={x: x_batch})" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[[-0.78515506 -0.43593025 -0.60911769 -0.17927292 -0.7393747 ]\n", + " [-0.99946702 -0.77885062 -0.99999893 0.99999279 -0.99988854]]\n", + "\n", + " [[-0.99369079 -0.81377232 -0.99814647 0.91571909 -0.99286312]\n", + " [ 0.03580528 0.68118596 0.82371414 0.70241606 -0.66689587]]\n", + "\n", + " [[-0.99983364 -0.94772995 -0.99999297 0.99730957 -0.99982893]\n", + " [-0.98845702 -0.08552338 -0.99856955 0.99975467 -0.99876517]]\n", + "\n", + " [[ 0.81873059 -0.87313306 -0.97621185 0.99987423 0.58628058]\n", + " [-0.8284685 -0.19498895 -0.66734689 0.93472785 -0.98051625]]]\n" + ] + } + ], + "source": [ + "print(outputs_val)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Setting the sequence lengths" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "tf.reset_default_graph()\n", + "\n", + "n_steps = 2\n", + "n_inputs = 3\n", + "n_units = 5\n", + "\n", + "x = tf.placeholder(tf.float32, [None, n_steps, n_inputs])\n", + "seq_len = tf.placeholder(tf.int32, [None,])\n", + "\n", + "cell = tf.contrib.rnn.BasicRNNCell(num_units=n_units)\n", + "outputs, states = tf.nn.dynamic_rnn(cell, x, sequence_length=seq_len, dtype=tf.float32)\n", + "\n", + "init = tf.global_variables_initializer()" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "x_batch = np.array([\n", + " # step 0 step 1\n", + " [[0, 1, 2], [9, 8, 7]], # instance 1\n", + " [[3, 4, 5], [0, 0, 0]], # instance 2 (padded with zero vectors)\n", + " [[6, 7, 8], [6, 5, 4]], # instance 3\n", + " [[9, 0, 1], [3, 2, 1]], # instance 4\n", + " ])\n", + "\n", + "seq_length_batch = np.array([2, 1, 2, 2])\n", + "\n", + "with tf.Session() as sess:\n", + " sess.run(init)\n", + " outputs_val, states_val = sess.run([outputs, states], feed_dict={x: x_batch, seq_len: seq_length_batch})" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[[-0.41555673 0.3124592 -0.70823008 -0.33731124 -0.89362472]\n", + " [ 0.98357052 0.99992394 -0.99998671 -0.96938699 -1. ]]\n", + "\n", + " [[ 0.04224264 0.96577072 -0.99503732 -0.81168658 -0.99997842]\n", + " [ 0. 0. 0. 0. 0. ]]\n", + "\n", + " [[ 0.48296547 0.99884307 -0.99992758 -0.95732415 -1. ]\n", + " [ 0.94608235 0.9987244 -0.99961239 -0.94665825 -0.99997342]]\n", + "\n", + " [[ 0.99636436 0.93347925 -0.99988347 -0.69118667 -0.99979246]\n", + " [ 0.80112863 0.94465852 -0.97441888 -0.78073817 -0.8295415 ]]]\n" + ] + } + ], + "source": [ + "print(outputs_val)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 0.98357052 0.99992394 -0.99998671 -0.96938699 -1. ]\n", + " [ 0.04224264 0.96577072 -0.99503732 -0.81168658 -0.99997842]\n", + " [ 0.94608235 0.9987244 -0.99961239 -0.94665825 -0.99997342]\n", + " [ 0.80112863 0.94465852 -0.97441888 -0.78073817 -0.8295415 ]]\n" + ] + } + ], + "source": [ + "print(states_val)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Training a sequence classifier" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "tf.reset_default_graph()\n", + "\n", + "n_steps = 28\n", + "n_inputs = 28\n", + "n_units = 150\n", + "n_outputs = 10\n", + "\n", + "learning_rate = 0.001\n", + "\n", + "x = tf.placeholder(tf.float32, [None, n_steps, n_inputs])\n", + "y = tf.placeholder(tf.int32, [None,])\n", + "\n", + "with tf.variable_scope(\"rnn\", initializer=tf.contrib.layers.variance_scaling_initializer()):\n", + " cell = tf.contrib.rnn.BasicRNNCell(num_units=n_units, activation=tf.nn.relu)\n", + " outputs, states = tf.nn.dynamic_rnn(cell, x, dtype=tf.float32)\n", + " \n", + "logits = tf.layers.dense(states, n_outputs) # fully connected layer\n", + "entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=y)\n", + "loss = tf.reduce_mean(entropy)\n", + "train_op = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)\n", + "\n", + "correct = tf.nn.in_top_k(logits, y, 1)\n", + "accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))\n", + "\n", + "init = tf.global_variables_initializer()" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Successfully downloaded train-images-idx3-ubyte.gz 9912422 bytes.\n", + "Extracting /tmp/data/train-images-idx3-ubyte.gz\n", + "Successfully downloaded train-labels-idx1-ubyte.gz 28881 bytes.\n", + "Extracting /tmp/data/train-labels-idx1-ubyte.gz\n", + "Successfully downloaded t10k-images-idx3-ubyte.gz 1648877 bytes.\n", + "Extracting /tmp/data/t10k-images-idx3-ubyte.gz\n", + "Successfully downloaded t10k-labels-idx1-ubyte.gz 4542 bytes.\n", + "Extracting /tmp/data/t10k-labels-idx1-ubyte.gz\n" + ] + } + ], + "source": [ + "from tensorflow.examples.tutorials.mnist import input_data\n", + "mnist = input_data.read_data_sets(\"/tmp/data/\")\n", + "X_test = mnist.test.images.reshape((-1, n_steps, n_inputs))\n", + "y_test = mnist.test.labels" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 Train accuracy: 0.933333 Test accuracy: 0.9163\n", + "1 Train accuracy: 0.946667 Test accuracy: 0.9475\n", + "2 Train accuracy: 0.953333 Test accuracy: 0.9582\n", + "3 Train accuracy: 0.953333 Test accuracy: 0.963\n", + "4 Train accuracy: 0.96 Test accuracy: 0.9679\n", + "5 Train accuracy: 0.973333 Test accuracy: 0.9625\n", + "6 Train accuracy: 0.946667 Test accuracy: 0.9682\n", + "7 Train accuracy: 0.96 Test accuracy: 0.9657\n", + "8 Train accuracy: 0.966667 Test accuracy: 0.97\n", + "9 Train accuracy: 0.993333 Test accuracy: 0.9764\n", + "10 Train accuracy: 0.966667 Test accuracy: 0.9669\n", + "11 Train accuracy: 0.98 Test accuracy: 0.9727\n", + "12 Train accuracy: 0.973333 Test accuracy: 0.966\n", + "13 Train accuracy: 0.953333 Test accuracy: 0.97\n", + "14 Train accuracy: 0.986667 Test accuracy: 0.9769\n", + "15 Train accuracy: 0.986667 Test accuracy: 0.9794\n", + "16 Train accuracy: 0.993333 Test accuracy: 0.9767\n", + "17 Train accuracy: 0.986667 Test accuracy: 0.9761\n", + "18 Train accuracy: 0.973333 Test accuracy: 0.9773\n", + "19 Train accuracy: 0.973333 Test accuracy: 0.9766\n", + "20 Train accuracy: 0.98 Test accuracy: 0.9796\n", + "21 Train accuracy: 0.986667 Test accuracy: 0.9759\n", + "22 Train accuracy: 0.986667 Test accuracy: 0.9783\n", + "23 Train accuracy: 0.993333 Test accuracy: 0.9783\n", + "24 Train accuracy: 1.0 Test accuracy: 0.9772\n", + "25 Train accuracy: 0.973333 Test accuracy: 0.9786\n", + "26 Train accuracy: 0.993333 Test accuracy: 0.9775\n", + "27 Train accuracy: 0.966667 Test accuracy: 0.9768\n", + "28 Train accuracy: 0.993333 Test accuracy: 0.9777\n", + "29 Train accuracy: 0.986667 Test accuracy: 0.9806\n", + "30 Train accuracy: 0.973333 Test accuracy: 0.978\n", + "31 Train accuracy: 0.993333 Test accuracy: 0.9808\n", + "32 Train accuracy: 0.993333 Test accuracy: 0.9776\n", + "33 Train accuracy: 1.0 Test accuracy: 0.9777\n", + "34 Train accuracy: 0.993333 Test accuracy: 0.9774\n", + "35 Train accuracy: 0.993333 Test accuracy: 0.9779\n", + "36 Train accuracy: 1.0 Test accuracy: 0.98\n", + "37 Train accuracy: 1.0 Test accuracy: 0.9779\n", + "38 Train accuracy: 0.993333 Test accuracy: 0.9814\n", + "39 Train accuracy: 0.993333 Test accuracy: 0.9769\n", + "40 Train accuracy: 0.98 Test accuracy: 0.9777\n", + "41 Train accuracy: 1.0 Test accuracy: 0.9807\n", + "42 Train accuracy: 0.993333 Test accuracy: 0.981\n", + "43 Train accuracy: 0.986667 Test accuracy: 0.98\n", + "44 Train accuracy: 0.993333 Test accuracy: 0.983\n", + "45 Train accuracy: 1.0 Test accuracy: 0.9781\n", + "46 Train accuracy: 0.986667 Test accuracy: 0.9788\n", + "47 Train accuracy: 0.986667 Test accuracy: 0.979\n", + "48 Train accuracy: 1.0 Test accuracy: 0.9809\n", + "49 Train accuracy: 1.0 Test accuracy: 0.982\n", + "50 Train accuracy: 0.993333 Test accuracy: 0.9822\n", + "51 Train accuracy: 0.986667 Test accuracy: 0.9782\n", + "52 Train accuracy: 1.0 Test accuracy: 0.9804\n", + "53 Train accuracy: 1.0 Test accuracy: 0.9794\n", + "54 Train accuracy: 0.993333 Test accuracy: 0.9785\n", + "55 Train accuracy: 1.0 Test accuracy: 0.9833\n", + "56 Train accuracy: 1.0 Test accuracy: 0.9807\n", + "57 Train accuracy: 0.993333 Test accuracy: 0.9829\n", + "58 Train accuracy: 1.0 Test accuracy: 0.9819\n", + "59 Train accuracy: 1.0 Test accuracy: 0.9792\n", + "60 Train accuracy: 1.0 Test accuracy: 0.9799\n", + "61 Train accuracy: 1.0 Test accuracy: 0.9807\n", + "62 Train accuracy: 0.986667 Test accuracy: 0.9764\n", + "63 Train accuracy: 0.993333 Test accuracy: 0.9793\n", + "64 Train accuracy: 0.993333 Test accuracy: 0.9805\n", + "65 Train accuracy: 1.0 Test accuracy: 0.9832\n", + "66 Train accuracy: 0.993333 Test accuracy: 0.9764\n", + "67 Train accuracy: 0.993333 Test accuracy: 0.9783\n", + "68 Train accuracy: 1.0 Test accuracy: 0.9811\n", + "69 Train accuracy: 1.0 Test accuracy: 0.9767\n", + "70 Train accuracy: 1.0 Test accuracy: 0.9801\n", + "71 Train accuracy: 0.993333 Test accuracy: 0.9824\n", + "72 Train accuracy: 1.0 Test accuracy: 0.9803\n", + "73 Train accuracy: 0.993333 Test accuracy: 0.9797\n", + "74 Train accuracy: 0.993333 Test accuracy: 0.9781\n", + "75 Train accuracy: 0.986667 Test accuracy: 0.9821\n", + "76 Train accuracy: 1.0 Test accuracy: 0.9808\n", + "77 Train accuracy: 0.993333 Test accuracy: 0.9785\n", + "78 Train accuracy: 0.993333 Test accuracy: 0.9808\n", + "79 Train accuracy: 0.98 Test accuracy: 0.981\n", + "80 Train accuracy: 1.0 Test accuracy: 0.9824\n", + "81 Train accuracy: 1.0 Test accuracy: 0.9836\n", + "82 Train accuracy: 1.0 Test accuracy: 0.9821\n", + "83 Train accuracy: 0.993333 Test accuracy: 0.978\n", + "84 Train accuracy: 1.0 Test accuracy: 0.9815\n", + "85 Train accuracy: 0.986667 Test accuracy: 0.9799\n", + "86 Train accuracy: 0.98 Test accuracy: 0.9813\n", + "87 Train accuracy: 1.0 Test accuracy: 0.9796\n", + "88 Train accuracy: 0.986667 Test accuracy: 0.9801\n", + "89 Train accuracy: 0.993333 Test accuracy: 0.9785\n", + "90 Train accuracy: 1.0 Test accuracy: 0.9817\n", + "91 Train accuracy: 1.0 Test accuracy: 0.9825\n", + "92 Train accuracy: 1.0 Test accuracy: 0.9809\n", + "93 Train accuracy: 1.0 Test accuracy: 0.9828\n", + "94 Train accuracy: 1.0 Test accuracy: 0.9809\n", + "95 Train accuracy: 0.993333 Test accuracy: 0.9801\n", + "96 Train accuracy: 1.0 Test accuracy: 0.9841\n", + "97 Train accuracy: 0.973333 Test accuracy: 0.9801\n", + "98 Train accuracy: 0.993333 Test accuracy: 0.9801\n", + "99 Train accuracy: 0.993333 Test accuracy: 0.9814\n" + ] + } + ], + "source": [ + "n_epochs = 100\n", + "batch_size = 150\n", + "\n", + "with tf.Session() as sess:\n", + " sess.run(init)\n", + " for epoch in range(n_epochs):\n", + " for itr in range(mnist.train.num_examples // batch_size):\n", + " X_batch, y_batch = mnist.train.next_batch(batch_size)\n", + " X_batch = X_batch.reshape((-1, n_steps, n_inputs))\n", + " sess.run(train_op, feed_dict={x: X_batch, y: y_batch})\n", + " acc_train = accuracy.eval(feed_dict={x: X_batch, y: y_batch})\n", + " acc_test = accuracy.eval(feed_dict={x: X_test, y: y_test})\n", + " print(epoch, \"Train accuracy:\", acc_train, \"Test accuracy:\", acc_test)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Multi-layer RNN" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "tf.reset_default_graph()\n", + "\n", + "n_steps = 28\n", + "n_inputs = 28\n", + "n_units1 = 150\n", + "n_units2 = 100\n", + "n_outputs= 10\n", + "\n", + "batch_size = 150\n", + "\n", + "learning_rate = 0.001\n", + "\n", + "x = tf.placeholder(tf.float32, [None, n_steps, n_inputs])\n", + "y = tf.placeholder(tf.int32, [None,])\n", + "\n", + "basic_cell1 = tf.contrib.rnn.BasicRNNCell(num_units=n_units1, activation=tf.nn.relu)\n", + "basic_cell2 = tf.contrib.rnn.BasicRNNCell(num_units=n_units2, activation=tf.nn.relu)\n", + "cell = tf.contrib.rnn.MultiRNNCell([basic_cell1, basic_cell2])\n", + "\n", + "outputs, states_tuple = tf.nn.dynamic_rnn(cell, x, dtype=tf.float32)\n", + "\n", + "states = tf.concat(values=states_tuple, axis=1)\n", + "logits = tf.layers.dense(states, n_outputs)\n", + "\n", + "entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=y)\n", + "loss = tf.reduce_mean(entropy)\n", + "\n", + "train_op = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)\n", + "\n", + "correct = tf.nn.in_top_k(logits, y, 1)\n", + "accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))\n", + "\n", + "init = tf.global_variables_initializer()" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 Train accuracy: 0.933333 Test accuracy: 0.9364\n", + "1 Train accuracy: 0.966667 Test accuracy: 0.9673\n", + "2 Train accuracy: 0.98 Test accuracy: 0.9724\n", + "3 Train accuracy: 0.986667 Test accuracy: 0.9749\n", + "4 Train accuracy: 0.986667 Test accuracy: 0.9749\n", + "5 Train accuracy: 0.96 Test accuracy: 0.9754\n", + "6 Train accuracy: 0.993333 Test accuracy: 0.9733\n", + "7 Train accuracy: 0.993333 Test accuracy: 0.9744\n", + "8 Train accuracy: 1.0 Test accuracy: 0.9744\n", + "9 Train accuracy: 0.98 Test accuracy: 0.9791\n", + "10 Train accuracy: 1.0 Test accuracy: 0.9782\n", + "11 Train accuracy: 1.0 Test accuracy: 0.9765\n", + "12 Train accuracy: 1.0 Test accuracy: 0.9827\n", + "13 Train accuracy: 0.993333 Test accuracy: 0.9757\n", + "14 Train accuracy: 0.993333 Test accuracy: 0.9798\n", + "15 Train accuracy: 0.993333 Test accuracy: 0.9773\n", + "16 Train accuracy: 0.986667 Test accuracy: 0.9812\n", + "17 Train accuracy: 0.993333 Test accuracy: 0.9848\n", + "18 Train accuracy: 0.993333 Test accuracy: 0.9814\n", + "19 Train accuracy: 0.993333 Test accuracy: 0.9765\n", + "20 Train accuracy: 0.993333 Test accuracy: 0.9834\n", + "21 Train accuracy: 0.993333 Test accuracy: 0.9835\n", + "22 Train accuracy: 1.0 Test accuracy: 0.982\n", + "23 Train accuracy: 0.993333 Test accuracy: 0.9798\n", + "24 Train accuracy: 1.0 Test accuracy: 0.9842\n", + "25 Train accuracy: 1.0 Test accuracy: 0.9837\n", + "26 Train accuracy: 0.986667 Test accuracy: 0.9867\n", + "27 Train accuracy: 0.986667 Test accuracy: 0.9834\n", + "28 Train accuracy: 1.0 Test accuracy: 0.984\n", + "29 Train accuracy: 0.993333 Test accuracy: 0.9821\n", + "30 Train accuracy: 1.0 Test accuracy: 0.9839\n", + "31 Train accuracy: 1.0 Test accuracy: 0.9845\n", + "32 Train accuracy: 0.986667 Test accuracy: 0.9809\n", + "33 Train accuracy: 0.986667 Test accuracy: 0.9801\n", + "34 Train accuracy: 1.0 Test accuracy: 0.9834\n", + "35 Train accuracy: 0.993333 Test accuracy: 0.9802\n", + "36 Train accuracy: 0.993333 Test accuracy: 0.9834\n", + "37 Train accuracy: 1.0 Test accuracy: 0.9856\n", + "38 Train accuracy: 0.993333 Test accuracy: 0.9851\n", + "39 Train accuracy: 0.986667 Test accuracy: 0.9862\n", + "40 Train accuracy: 1.0 Test accuracy: 0.9862\n", + "41 Train accuracy: 1.0 Test accuracy: 0.9837\n", + "42 Train accuracy: 0.993333 Test accuracy: 0.9823\n", + "43 Train accuracy: 1.0 Test accuracy: 0.9846\n", + "44 Train accuracy: 1.0 Test accuracy: 0.9837\n", + "45 Train accuracy: 0.993333 Test accuracy: 0.9841\n", + "46 Train accuracy: 1.0 Test accuracy: 0.9861\n", + "47 Train accuracy: 0.986667 Test accuracy: 0.9815\n", + "48 Train accuracy: 1.0 Test accuracy: 0.9824\n", + "49 Train accuracy: 1.0 Test accuracy: 0.9853\n", + "50 Train accuracy: 1.0 Test accuracy: 0.9856\n", + "51 Train accuracy: 1.0 Test accuracy: 0.9835\n", + "52 Train accuracy: 0.986667 Test accuracy: 0.9867\n", + "53 Train accuracy: 1.0 Test accuracy: 0.9838\n", + "54 Train accuracy: 1.0 Test accuracy: 0.9848\n", + "55 Train accuracy: 0.993333 Test accuracy: 0.9846\n", + "56 Train accuracy: 1.0 Test accuracy: 0.9843\n", + "57 Train accuracy: 0.993333 Test accuracy: 0.982\n", + "58 Train accuracy: 0.993333 Test accuracy: 0.9837\n", + "59 Train accuracy: 1.0 Test accuracy: 0.9864\n", + "60 Train accuracy: 1.0 Test accuracy: 0.9874\n", + "61 Train accuracy: 0.993333 Test accuracy: 0.9833\n", + "62 Train accuracy: 0.993333 Test accuracy: 0.9861\n", + "63 Train accuracy: 1.0 Test accuracy: 0.9811\n", + "64 Train accuracy: 1.0 Test accuracy: 0.9875\n", + "65 Train accuracy: 1.0 Test accuracy: 0.987\n", + "66 Train accuracy: 1.0 Test accuracy: 0.9872\n", + "67 Train accuracy: 1.0 Test accuracy: 0.9858\n", + "68 Train accuracy: 1.0 Test accuracy: 0.9878\n", + "69 Train accuracy: 1.0 Test accuracy: 0.9872\n", + "70 Train accuracy: 1.0 Test accuracy: 0.9878\n", + "71 Train accuracy: 1.0 Test accuracy: 0.9866\n", + "72 Train accuracy: 0.993333 Test accuracy: 0.9874\n", + "73 Train accuracy: 1.0 Test accuracy: 0.9832\n", + "74 Train accuracy: 1.0 Test accuracy: 0.9865\n", + "75 Train accuracy: 0.993333 Test accuracy: 0.986\n", + "76 Train accuracy: 0.986667 Test accuracy: 0.9865\n", + "77 Train accuracy: 1.0 Test accuracy: 0.9854\n", + "78 Train accuracy: 0.993333 Test accuracy: 0.9875\n", + "79 Train accuracy: 1.0 Test accuracy: 0.9843\n", + "80 Train accuracy: 1.0 Test accuracy: 0.9853\n", + "81 Train accuracy: 0.993333 Test accuracy: 0.9858\n", + "82 Train accuracy: 1.0 Test accuracy: 0.9866\n", + "83 Train accuracy: 1.0 Test accuracy: 0.9855\n", + "84 Train accuracy: 1.0 Test accuracy: 0.9849\n", + "85 Train accuracy: 1.0 Test accuracy: 0.9872\n", + "86 Train accuracy: 1.0 Test accuracy: 0.9855\n", + "87 Train accuracy: 1.0 Test accuracy: 0.9822\n", + "88 Train accuracy: 1.0 Test accuracy: 0.9859\n", + "89 Train accuracy: 1.0 Test accuracy: 0.9851\n", + "90 Train accuracy: 1.0 Test accuracy: 0.9865\n", + "91 Train accuracy: 1.0 Test accuracy: 0.9858\n", + "92 Train accuracy: 1.0 Test accuracy: 0.9853\n", + "93 Train accuracy: 0.986667 Test accuracy: 0.9799\n", + "94 Train accuracy: 0.993333 Test accuracy: 0.9825\n", + "95 Train accuracy: 1.0 Test accuracy: 0.9874\n", + "96 Train accuracy: 1.0 Test accuracy: 0.9852\n", + "97 Train accuracy: 1.0 Test accuracy: 0.9862\n", + "98 Train accuracy: 1.0 Test accuracy: 0.9818\n", + "99 Train accuracy: 1.0 Test accuracy: 0.9864\n" + ] + } + ], + "source": [ + "n_epochs = 100\n", + "\n", + "with tf.Session() as sess:\n", + " sess.run(init)\n", + " for epoch in range(n_epochs):\n", + " for itr in range(mnist.train.num_examples // batch_size):\n", + " X_batch, y_batch = mnist.train.next_batch(batch_size)\n", + " X_batch = X_batch.reshape((-1, n_steps, n_inputs))\n", + " sess.run(train_op, feed_dict={x: X_batch, y: y_batch})\n", + " acc_train = accuracy.eval(feed_dict={x: X_batch, y: y_batch})\n", + " acc_test = accuracy.eval(feed_dict={x: X_test, y: y_test})\n", + " print(epoch, \"Train accuracy:\", acc_train, \"Test accuracy:\", acc_test)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Time series" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "t_min, t_max = 0, 30\n", + "resolution = 0.1\n", + "\n", + "def time_series(t):\n", + " return t * np.sin(t) / 3 + 2 * np.sin(t * 5)\n", + "\n", + "def next_batch(batch_size, n_steps):\n", + " t0 = np.random.rand(batch_size, 1) * (t_max - t_min - n_steps * resolution)\n", + " Ts = t0 + np.arange(0, n_steps + 1) * resolution\n", + " ys = time_series(Ts)\n", + " return ys[:, :-1].reshape(-1, n_steps, 1), ys[:, 1:].reshape(-1, n_steps, 1)" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "d:\\anaconda3\\envs\\tf_new\\lib\\site-packages\\ipykernel\\__main__.py:1: DeprecationWarning: object of type cannot be safely interpreted as an integer.\n", + " if __name__ == '__main__':\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saving figure time_series_plot\n" + ] + }, + { + "data": { + "image/png": "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\nz6a6urrWOjWrMKWnp/PII49wyy23EBsbS2pqKk8++WSt/ezcuZNRo0YRHh5Or169+PDDD4mOjubl\nl19u8HhrVmFyxvrMM8/QuXNn2rdvz4033khxcbFrna+//prhw4cTHR1Nu3btGDp0KJs3b2b58uXc\neOONFBUVuc7d3LlzAXj11VcZMmQIMTExJCcnM3XqVA4fPuza5vLlyxERPv/8c4YNG0ZkZCRZWVms\nW7euVryrV69m7NixREVF0a5dO8aOHUtOTg4AxhieeOIJMjIyiIiIoH///k0u+VFKKaWUag6aQLgh\nYt3UFIsWLSItLY3+/ftz/fXX849//KPBkoPZs2fz85//nPHjx3PkyBGOHDnCiBEjXMvvv/9+Zs6c\nydatW7niiisoLS3lggsu4IMPPmDLli3MmjWLW265hc8//7zBuF577TWCg4NZtWoV8+bN489//jNv\nvfVWg+/505/+RP/+/Vm3bh1z5szhV7/6Fd9++y0A1dXVXHnllQQHB7N69WpefvllHnroIcrKyppw\ntuy++eYbNm/ezGeffcZbb73F4sWLeeaZZwCorKxk8uTJ/OhHP2LDhg2sWbOGO++8k6CgIEaMGMGf\n//xnIiMjXedu9uzZAJSXl/PQQw+xYcMGPvjgA3Jzc7nmmmvq7fv+++/nf//3f1m3bh0JCQlMmzYN\nYwwAGzZsYMyYMfTo0YOVK1eyevVqrr76aiorKwF48MEHefHFF3n22WfZunUr999/P7fccgtLly5t\n8jlQSjWfPXtg5kxIjclnsVxJakw+M2fa5yullN8yxvj9NHjwYOPJ1q1b680D66amGDVqlHnyySeN\nMcZUV1ebtLQ08/bbbzf4nunTp5tLL7201rx9+/YZwDz11FON7vPqq682N910k8ftjRo1ygwfPrzW\ne8aPH1/rPaNGjTK3336763VaWpr5xS9+Ues9PXr0MA8//LAxxpiPPvrIBAUFmezsbNfylStXGsAs\nWLDAY6y/+93vTN++fWvFmpqaaiorK13z/vu//9uMGzfOGGPMyZMnDWCWL1/udnsLFiwwUVFRHvfn\ntG3bNgOYQ4cOGWOM+fLLLw1gPvroI9c6K1asqLXOtddeW++8ORUWFprw8HDz9ddf15o/a9YsM3Hi\nxEbjaYy7vwGlagLWGh/4Lvdmauj7vrl9+KExkZHGhIQYcx3/MAbMNF4xISH2+R9+2GqhKKVUs/D2\n+15LINqo3bt3s2LFCq699loARIRp06Y1Wo2pIVlZWbVeV1VV8eijjzJgwAASEhKIjo7mnXfe4eDB\ngw1uZ8CAAbVep6SkcPz48bN+z/bt20lJSaFz586u5UOGDMFma/rHNzMzk6CgILf7iY+P54YbbmDC\nhAlceuml/PGPf2z0WMHekH3y5MmkpaURExPjOo9131vzGFNSUgBc+/7+++8ZO3as2+1v3bqV0tJS\nfvKTnxAdHe2annvuOfboY06lLLFnD0yZAsXFUFEBv+QlwP6zosI+f8oULYlQSvknHYnaDWOsjqBx\n8+fPp6qqiq5du7rmGUfghw4dokuXLk3eZlRUVK3XTz31FE8//TTPPPMM/fv3Jzo6ml//+teNJgMh\nISG1XotIrTYQzfWes9HYfhYsWMCdd97JRx99xHvvvccDDzzAkiVLmDBhgtvtFRUVMWHCBMaPH88r\nr7xCcnIyubm5XHTRRZSXl3vctzjqq3lzjM513n///VrX293xKKVaR/mo8RQVn6nOWUYoACNZicFR\nH7UYto8eB4c+syJEpZRqMVoC0QZVVlaycOFCHn/8cdavX++aNmzYwIABA+o1dK4pNDSUqqoqr/az\nYsUKJk2axPXXX8+gQYPIyMhg586dzXUYXuvduzc5OTmuBsUAa9eubZEEA2DgwIHMmTOH5cuXM3r0\naBYuXAi4P3fbt28nNzeXxx57jIsvvpjevXs3mmC5c/755/PFF1+4XZaZmUlYWBgHDhygR48etaa0\ntLSmH6BS6pzNPvUARUS6XodRXusnQBGR3HPqwVaPTSmlWppPJRAicoeIrBWRMhF5uc6ydBExIlJY\nY/qNRaFaaunSpeTm5nLzzTfTr1+/WtMvfvELFixY4CqNqCs9PZ3NmzezY8cOcnNzG2x03bNnTz7/\n/HNWrFjB9u3bueOOO9i3b19LHZZHl1xyCb169WL69Ols2LCB1atXc/fddxMcHOx6kt8c9u3bx333\n3ceqVas4cOAAX375JRs3biQzMxOwn7vS0lI+/fRTcnNzKS4upmvXroSFhTFv3jz27t3L0qVL+c1v\nmv6xvPfee/n++++ZMWMGGzZsYMeOHcyfP5+DBw8SExPD7NmzmT17Ni+99BK7d+9m/fr1PP/887zw\nwgvNdvxKKe8tKx3DZXxQK4moqYhILmUpH5WObt3AlFKqFfhUAgHkAI+AozKpe3HGmGjH9HArxeVT\nXnzxRcaMGeN2jIOpU6eyf/9+Pv30U7fvvfnmm+nTpw9ZWVkkJSWxcuVKj/t58MEHGTp0KBMnTuTi\niy8mKiqKadOmNdtxeMtms7F48WLKysoYOnQo06dP54EHHkBECA8Pb7b9REZGsnPnTqZOnUrPnj2Z\nPn0606ZNY86cOQCMGDGCW2+9lWuuuYakpCSeeOIJkpKSWLhwIUuWLCEzM5OHHnqIP/7xj03e96BB\ng/jss8/Yvn07w4cPZ9iwYbz55puuKkoPP/wwc+fO5amnnqJv375ccskl/Otf/6Jbt27NdvxKKe9F\nR8NyxnA1b1FC7e+hEsK5mrf4itHo2JNKKX8knp5UW0lEHgFSjTE31JiXDuwDQowxlU3ZXlZWllm7\ndq3bZdu2baNPnz5nHauyxoYNGxg0aBBr165l8ODBVofTpunfgGqMiPzHGJPV+JrWa+j73pM9e+Dp\np+HVV6Gw0J4cXHcd3HMPZGS4f8/MmTB/Pvy84lWe4zYiKKacMEIpo4RIbuM5/hlyHTNmwLx5zXBg\nSinVCrz9vve1EghvHBCRbBFZICKJnlYSkRmO6lBrT5w40ZrxqRawePFiPvnkE/bt28eXX37JDTfc\nwMCBA7ngggusDk0p1YYtWwYDBtiTgYICeycaBQX21wMG2Je7c889EBICN/EikRSzkYFM5l02MpBI\nivklLxESAnfd1brHo5RSraEtJRC5wBAgDRgMxACveVrZGPOCMSbLGJOVlJTUSiGqllJQUMAdd9xB\nZmYm06ZNo0+fPnz88cfN2gZCKRVY6nbFWlNjXbFmZMCiRVBoa8cc25NksZbPuIQhfMd9ticossWy\naJHnEgyllGrLWi2BEJHljkbQ7qYVjb3fGFNojFlrjKk0xhwD7gB+LCIxLR+9stp//dd/sXPnTkpK\nSsjJyeH111+nQ4cOVoellGrDnn66fuJQV0UF/OlP7pdNnAiZO5dQetvdxMTasNkgOjaIktvuIXPn\nEiZObP6YlVLKF7TaOBDGmNHNvUnHz7ZUiqKUUspHvPqqdwnEK694bseQkWFfpu0clFKBxKduvkUk\nWETCgSAgSETCRSTYsWyYiPQSEZuIJAD/Byw3xuSf6359sSG5Uq1BP/sqkBUWNu96SikVKHwqgQAe\nBEqA+4DrHL87R+HpDnwEFACbgTLgmnPdYUhICCUlJee6GaXapJKSEh3NWgUsb7tY1a5YlVKqNp9K\nIIwxc40xUmea61j2hjGmmzEmyhjTyRjzX8aYo+e6z+TkZA4fPkxxcbE+jVUBwxhDcXExhw8fJjk5\n2epwlLLEddfZe1JqSEgIXH9968SjlFJtRau1gfBVsbGxAOTk5DQ4KrNS/iYkJIQOHTq4/gaUCjT3\n3AMLFzbcDkK7YlVKqfoCPoEAexKhN1FKKRVYnF2xTpliTyJqJhIhIfZJu2JVSqn6fKoKk1JKKdWa\nJk6EjRthxgyIjQWbzf5zxgz7fO2KVSml6tMSCKWUUgFNu2JVSqmm0RIIpZRSSimllNc0gVBKKaWU\nUkp5TRMIpZRSSimllNckEMY+EJECYIfVcbSgRCDX6iBamL8fox5f2+bvx9fLGBNjdRDeEJETwAGr\n42gl/v65aw56jhqn56hxgXSO0owxSY2tFCiNqHcYY7KsDqKliMhafz4+8P9j1ONr2wLh+KyOwVve\n/OPzF/7+uWsOeo4ap+eocXqO6tMqTEoppZRSSimvaQKhlFJKKaWU8lqgJBAvWB1AC/P34wP/P0Y9\nvrZNj09ZQa9L4/QcNU7PUeP0HNUREI2olVJKKaWUUs0jUEoglFJKKaWUUs1AEwillFJKKaWU1zSB\nUEoppZRSSnnNrxMIEYkXkcUiUiQiB0TkWqtjam4islxESkWk0DG12QHzROQOEVkrImUi8nKdZeNE\nZLuIFIvIlyKSZlGY58TTMYpIuoiYGtexUER+Y2GoTSYiYSLyouNvrUBE1ovIxBrL2/Q1bOj4/OH6\nOYnIqyJyRER+EJGdIvLfNZa16Wvo6xr4fhguIp+KyCkROSEib4tIpwa24zf/F+pq4BxlOuafdkyf\niUhmA9vx2/uDZjxHAfc5qrPObx3f6+Mb2E6647uw2PHd6HFdf+PXCQTwLFAOdACmAc+JSF9rQ2oR\ndxhjoh1TL6uDOQc5wCPASzVnikgi8A7wGyAeWAu81erRNQ+3x1hDXI1r+XArxtUcgoFDwCigHfAg\n8E/HF6w/XEOPx1djnbZ8/ZweB9KNMbHA5cAjIjLYT66hr/P0/dAeey8w6UAaUAAsaGRb/vJ/oS5P\n5ygHmIL9s5kIvAe82cB2/Pn+oLnOEQTe5wgAEckApgJHGtnOG8D3QALwALBIRAJiMEu/HYlaRKKA\nnwH9jDGFwAoReQ+4HrjP0uCUW8aYdwBEJAtIrbHoKmCLMeZtx/K5QK6I9DbGbG/1QM9BA8fY5hlj\nioC5NWZ9ICL7gMHYv1zb9DVs5Pj+Y0lQLcAYs6XmS8eUgf042/Q19HWevh+MMctqridkNq3XAAAG\nhklEQVQi84CvWjc639DAOcoD8hzLBKgCerjbhr/fHzTHOfJ3XvwvfhaYA/zV0zZEpCdwAfBjY0wJ\n8C8RuRP7Z+v5Zg/ax/hzCURPoNIYs7PGvA2AvzxhqOlxEckVkZUiMtrqYFpAX+zXDnDdyO3BP6/l\nARHJFpEFjie+bZaIdMD+d7gFP7yGdY7PyS+un4j8VUSKge3Yn8B9iB9ewzbsYmp/7tzx9/8LbolI\nHlAK/AV4zMNqgXR/UI+X58gp4D5HIjIVKDPGfNjIqn2BvcaYghrzAuZz5M8JRDTwQ515+UCMBbG0\npDlAd6Az9iLu9x1Fb/4kGvu1q8nfrmUuMAR79YTB2I/tNUsjOgciEoI9/oWOp9N+dQ3dHJ9fXT9j\nzEzsx3AR9mpLZfjZNWyrRGQA8Fvg3gZWC4T/C24ZY+KwVzG8A3vVEncC5f7ALS/PEQTg50hEYrAn\nVbO8WD2gvxP9OYEoBGLrzIvFXnfUbxhj1hhjCowxZcaYhcBK4KdWx9XM/P5aGmMKjTFrjTGVxphj\n2L/Yf+z4MmtTRMQGvIK9fvEdjtl+cw3dHZ8/XT8nY0yVMWYF9uL92/Cja9hWiUgPYBkwyxjzjaf1\nAuT/gkeO0rHngX+ISLKbVQL+s+zFOQrUz9Fc4BVjzH4v1g3oz5E/JxA7gWAROa/GvIE0Xuzb1hlA\nrA6imW3Bfu0AV/3VDPz7WjqHiG9Tf6OOerUvYm+Y+DNjTIVjkV9cwwaOr642ef08CObMtWrz17Ct\nEnuPV58BDxtjXmni2/3x/0JjbEAk9qfndQXq/UFdDZ0jdwLhczQO+H8iclREjgJdsHeWMcfNuluA\n7nUeFAXM58gf/rm55ciu3wF+LyJRIjISmIz9yaFfEJE4EZkgIuEiEiwi07DXjf3I6tjOhuMYwoEg\nIMh5XMBioJ+I/Myx/LfAxrbYcNPTMYrIMBHpJSI2EUkA/g9YboypWzzq654D+gCTHI3KnPzlGro9\nPn+5fiKSLCK/EJFoEQkSkQnANcDn+M819FkNfD90Br4A5hljGmyc6W//F+pq4BxdIiLnOz63scAf\ngdPAtrrb8Pf7g+Y4R4H6OcKeQPQDBjmmHOAW7I2qa3G0oVkP/M7x/iuBAcC/WukwrGWM8dsJe1dl\nS4Ai4CBwrdUxNfPxJQHfYS8uywNWA5dYHdc5HM9czvT64pzmOpaNx96gswRYjr2bSctjbq5jxH6T\nts/xWT0C/APoaHW8TTy2NMfxlGIv2nVO0/zhGjZ0fP5w/RzHmIS9d5887HXENwE311jepq+hr08N\nfD/8zvF7zc9dYY33/RpYVuMa+s3/hSaco6mOz2YhcAJYCgxwd44cr/32/qA5zlGgfo7crLcfGF/j\n9fPA8zVepzu+C0uAHTXX9fdJHCdAKaWUUkoppRrlt1WYlFJKKaWUUs1PEwillFJKKaWU1zSBUEop\npZRSSnlNEwillFJKKaWU1zSBUEoppZRSSnlNEwillFJKKaWU1zSBUKoViIgRkSlWx6GUUqpl6fe9\nCgSaQCh1Dhz/KBqaXnas2gl438JQlVJKnQP9vlfqDB1ITqlzICIda7y8DPg79n8eTiXGmPzWjUop\npVRz0+97pc7QEgilzoEx5qhzAvLqznP+M6lZpC0i6Y7XvxCRr0SkRES+F5EBItJPRFaJSJGIrBCR\nbjX3JyKTROQ/IlIqIvtE5FERCW31A1dKqQCj3/dKnaEJhFLWeQj4A3A+9n9GbwB/AR4AhgLhwP85\nVxaRCcBrwDygL/BLYArwWKtGrZRSqqn0+175FU0glLLOH40xHxpjtgNPA5nAX4wxXxpjtmD/xzGm\nxvoPAE8aYxYYY/YYY74E5gC3ioi0evRKKaW8pd/3yq8EWx2AUgFsY43fjzl+bqozL0pEIo0xxcBg\nYKiIzKmxjg2IADoCR1oyWKWUUmdNv++VX9EEQinrVNT43TQwz1bj50PA2262daJ5Q1NKKdWM9Pte\n+RVNIJRqO9YBvY0xu60ORCmlVIvS73vl0zSBUKrt+D3wgYgcAP4JVAL9gKHGmF9ZGplSSqnmpN/3\nyqdpI2ql2ghjzMfApdgb2v3bMd0HHLQyLqWUUs1Lv++Vr9OB5JRSSimllFJe0xIIpZRSSimllNc0\ngVBKKaWUUkp5TRMIpZRSSimllNc0gVBKKaWUUkp5TRMIpZRSSimllNc0gVBKKaWUUkp5TRMIpZRS\nSimllNc0gVBKKaWUUkp57f8DWA5nW7RGHecAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "t = np.linspace(t_min, t_max, (t_max - t_min) // resolution)\n", + "\n", + "n_steps = 20\n", + "t_instance = np.linspace(12.2, 12.2 + resolution * (n_steps + 1), n_steps + 1)\n", + "\n", + "plt.figure(figsize=(11,4))\n", + "plt.subplot(121)\n", + "plt.title(\"A time series (generated)\", fontsize=14)\n", + "plt.plot(t, time_series(t), label=r\"$t . \\sin(t) / 3 + 2 . \\sin(5t)$\")\n", + "plt.plot(t_instance[:-1], time_series(t_instance[:-1]), \"b-\", linewidth=3, label=\"A training instance\")\n", + "plt.legend(loc=\"lower left\", fontsize=14)\n", + "plt.axis([0, 30, -17, 13])\n", + "plt.xlabel(\"Time\")\n", + "plt.ylabel(\"Value\")\n", + "\n", + "plt.subplot(122)\n", + "plt.title(\"A training instance\", fontsize=14)\n", + "plt.plot(t_instance[:-1], time_series(t_instance[:-1]), \"bo\", markersize=10, label=\"instance\")\n", + "plt.plot(t_instance[1:], time_series(t_instance[1:]), \"r*\", markersize=10, label=\"target\")\n", + "plt.legend(loc=\"upper left\")\n", + "plt.xlabel(\"Time\")\n", + "\n", + "\n", + "save_fig(\"time_series_plot\")\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "X_batch, y_batch = next_batch(1, n_steps)" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[-3.40105091, -3.1535112 ],\n", + " [-3.1535112 , -2.4019374 ],\n", + " [-2.4019374 , -1.23833849],\n", + " [-1.23833849, 0.14769251],\n", + " [ 0.14769251, 1.51446705],\n", + " [ 1.51446705, 2.6264053 ],\n", + " [ 2.6264053 , 3.31071511],\n", + " [ 3.31071511, 3.49867895],\n", + " [ 3.49867895, 3.2414507 ],\n", + " [ 3.2414507 , 2.69650536],\n", + " [ 2.69650536, 2.08807012],\n", + " [ 2.08807012, 1.65123531],\n", + " [ 1.65123531, 1.57343979],\n", + " [ 1.57343979, 1.94766747],\n", + " [ 1.94766747, 2.74882441],\n", + " [ 2.74882441, 3.83908994],\n", + " [ 3.83908994, 5.00094079],\n", + " [ 5.00094079, 5.98977144],\n", + " [ 5.98977144, 6.59323507],\n", + " [ 6.59323507, 6.68278338]])" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.c_[X_batch[0], y_batch[0]]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Using ```OutputProjectionWrapper()```" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "tf.reset_default_graph()\n", + "\n", + "n_steps = 20\n", + "n_inputs = 1\n", + "n_units = 100\n", + "n_outputs = 1\n", + "\n", + "learning_rate = 0.001\n", + "\n", + "X = tf.placeholder(tf.float32, [None, n_steps, n_outputs])\n", + "y = tf.placeholder(tf.float32, [None, n_steps, n_outputs])\n", + "\n", + "cell = tf.contrib.rnn.OutputProjectionWrapper(tf.contrib.rnn.BasicRNNCell(num_units=n_units,\n", + " activation=tf.nn.relu), output_size = n_outputs)\n", + "outputs, states = tf.nn.dynamic_rnn(cell, X, dtype=tf.float32)\n", + "\n", + "loss = tf.reduce_sum(tf.square(outputs - y))\n", + "train_op = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)\n", + "\n", + "init = tf.global_variables_initializer()" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 0 MSE 16805.7\n", + "Epoch 100 MSE 478.19\n", + "Epoch 200 MSE 197.619\n", + "Epoch 300 MSE 134.71\n", + "Epoch 400 MSE 96.4492\n", + "Epoch 500 MSE 64.9992\n", + "Epoch 600 MSE 61.2047\n", + "Epoch 700 MSE 50.3473\n", + "Epoch 800 MSE 61.2037\n", + "Epoch 900 MSE 47.3403\n", + "[[[-3.38903462]\n", + " [-2.99062806]\n", + " [-2.05341138]\n", + " [-0.72228309]\n", + " [ 0.75538291]\n", + " [ 2.09516406]\n", + " [ 3.05094764]\n", + " [ 3.47993654]\n", + " [ 3.37980751]\n", + " [ 2.88802793]\n", + " [ 2.24353023]\n", + " [ 1.7210823 ]\n", + " [ 1.55604639]\n", + " [ 1.87980783]\n", + " [ 2.68328027]\n", + " [ 3.81833127]\n", + " [ 5.03675731]\n", + " [ 6.05632222]\n", + " [ 6.63608254]\n", + " [ 6.64072041]]]\n", + "[[[-3.51775551]\n", + " [-2.53501797]\n", + " [-1.15251982]\n", + " [ 0.60017455]\n", + " [ 1.98542166]\n", + " [ 3.06789064]\n", + " [ 3.54276776]\n", + " [ 3.362077 ]\n", + " [ 2.93283987]\n", + " [ 2.11475372]\n", + " [ 1.56365407]\n", + " [ 1.45852852]\n", + " [ 1.86208022]\n", + " [ 2.68589473]\n", + " [ 3.81468797]\n", + " [ 5.01798582]\n", + " [ 6.01481771]\n", + " [ 6.61353302]\n", + " [ 6.57810783]\n", + " [ 5.983284 ]]]\n" + ] + } + ], + "source": [ + "n_epochs = 1000\n", + "batch_size = 50\n", + "\n", + "with tf.Session() as sess:\n", + " sess.run(init)\n", + " for epoch in range(n_epochs):\n", + " X_batch, y_batch = next_batch(batch_size, n_steps)\n", + " sess.run(train_op, feed_dict={X: X_batch, y: y_batch})\n", + " if epoch % 100 == 0:\n", + " mse = sess.run(loss, feed_dict={X: X_batch, y: y_batch})\n", + " print(\"Epoch\", epoch, \"MSE\", mse)\n", + " \n", + " X_new = time_series(t_instance[:-1].reshape(-1, n_steps, n_inputs))\n", + " y_pred = sess.run(outputs, feed_dict={X: X_new})\n", + " print(X_new)\n", + " print(y_pred)" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saving figure time_series_pred_plot\n" + ] + }, + { + "data": { + "image/png": "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\nQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.title(\"Testing the model\", fontsize=14)\n", + "plt.plot(t_instance[:-1], time_series(t_instance[:-1]), \"bo\", markersize=10, label=\"instance\")\n", + "plt.plot(t_instance[1:], time_series(t_instance[1:]), \"y*\", markersize=10, label=\"target\")\n", + "plt.plot(t_instance[1:], y_pred[0,:,0], \"r.\", markersize=10, label=\"prediction\")\n", + "plt.legend(loc=\"upper left\")\n", + "plt.xlabel(\"Time\")\n", + "\n", + "save_fig(\"time_series_pred_plot\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Without using ```OutputProjectionWrapper```" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "tf.reset_default_graph()\n", + "\n", + "n_steps = 20\n", + "n_inputs = 1\n", + "n_units = 100\n", + "n_outputs = 1\n", + "\n", + "learning_rate = 0.001\n", + "\n", + "X = tf.placeholder(tf.float32, [None, n_steps, n_outputs])\n", + "y = tf.placeholder(tf.float32, [None, n_steps, n_outputs])\n", + "\n", + "cell = tf.contrib.rnn.BasicRNNCell(num_units=n_units, activation=tf.nn.relu)\n", + "rnn_outputs, states = tf.nn.dynamic_rnn(cell, X, dtype=tf.float32)\n", + "\n", + "stacked_rnn_outputs = tf.reshape(rnn_outputs, [-1, n_units])\n", + "stacked_outputs = tf.layers.dense(stacked_rnn_outputs, n_outputs)\n", + "outputs = tf.reshape(stacked_outputs, [-1, n_steps, n_outputs])\n", + "\n", + "loss = tf.reduce_sum(tf.square(outputs - y))\n", + "train_op = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)\n", + "\n", + "init = tf.global_variables_initializer()" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 0 MSE 12681.7\n", + "Epoch 100 MSE 611.424\n", + "Epoch 200 MSE 208.967\n", + "Epoch 300 MSE 103.201\n", + "Epoch 400 MSE 62.355\n", + "Epoch 500 MSE 63.4591\n", + "Epoch 600 MSE 56.7102\n", + "Epoch 700 MSE 58.3863\n", + "Epoch 800 MSE 44.6704\n", + "Epoch 900 MSE 52.3096\n", + "[[[-3.38903462]\n", + " [-2.99062806]\n", + " [-2.05341138]\n", + " [-0.72228309]\n", + " [ 0.75538291]\n", + " [ 2.09516406]\n", + " [ 3.05094764]\n", + " [ 3.47993654]\n", + " [ 3.37980751]\n", + " [ 2.88802793]\n", + " [ 2.24353023]\n", + " [ 1.7210823 ]\n", + " [ 1.55604639]\n", + " [ 1.87980783]\n", + " [ 2.68328027]\n", + " [ 3.81833127]\n", + " [ 5.03675731]\n", + " [ 6.05632222]\n", + " [ 6.63608254]\n", + " [ 6.64072041]]]\n", + "[[[-3.47104859]\n", + " [-2.4952054 ]\n", + " [-1.26815391]\n", + " [ 0.67656517]\n", + " [ 2.2081449 ]\n", + " [ 3.09208822]\n", + " [ 3.49673343]\n", + " [ 3.3366437 ]\n", + " [ 2.9629519 ]\n", + " [ 2.18085527]\n", + " [ 1.61444068]\n", + " [ 1.49737442]\n", + " [ 1.92812812]\n", + " [ 2.77589178]\n", + " [ 3.92481685]\n", + " [ 5.14265347]\n", + " [ 6.1297102 ]\n", + " [ 6.67620325]\n", + " [ 6.68489265]\n", + " [ 6.13003349]]]\n" + ] + } + ], + "source": [ + "n_epochs = 1000\n", + "batch_size = 50\n", + "\n", + "with tf.Session() as sess:\n", + " sess.run(init)\n", + " for epoch in range(n_epochs):\n", + " X_batch, y_batch = next_batch(batch_size, n_steps)\n", + " sess.run(train_op, feed_dict={X: X_batch, y: y_batch})\n", + " if epoch % 100 == 0:\n", + " mse = sess.run(loss, feed_dict={X: X_batch, y: y_batch})\n", + " print(\"Epoch\", epoch, \"MSE\", mse)\n", + " \n", + " X_new = time_series(t_instance[:-1].reshape(-1, n_steps, n_inputs))\n", + " y_pred = sess.run(outputs, feed_dict={X: X_new})\n", + " print(X_new)\n", + " print(y_pred)" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saving figure time_series_pred_plot\n" + ] + }, + { + "data": { + "image/png": "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\ngg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.title(\"Testing the model\", fontsize=14)\n", + "plt.plot(t_instance[:-1], time_series(t_instance[:-1]), \"bo\", markersize=10, label=\"instance\")\n", + "plt.plot(t_instance[1:], time_series(t_instance[1:]), \"y*\", markersize=10, label=\"target\")\n", + "plt.plot(t_instance[1:], y_pred[0,:,0], \"r.\", markersize=10, label=\"prediction\")\n", + "plt.legend(loc=\"upper left\")\n", + "plt.xlabel(\"Time\")\n", + "\n", + "save_fig(\"time_series_pred_plot\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Generating new sequence" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 0 MSE 18461.4\n", + "Epoch 100 MSE 775.334\n", + "Epoch 200 MSE 183.63\n", + "Epoch 300 MSE 86.1643\n", + "Epoch 400 MSE 62.2201\n", + "Epoch 500 MSE 55.894\n", + "Epoch 600 MSE 51.0927\n", + "Epoch 700 MSE 52.7136\n", + "Epoch 800 MSE 56.0478\n", + "Epoch 900 MSE 42.1387\n", + "Epoch 1000 MSE 57.3633\n", + "Epoch 1100 MSE 47.4708\n", + "Epoch 1200 MSE 50.8996\n", + "Epoch 1300 MSE 53.1064\n", + "Epoch 1400 MSE 44.7769\n", + "Saving figure creative_sequence_plot\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "n_epochs = 1500\n", + "batch_size = 50\n", + "\n", + "with tf.Session() as sess:\n", + " sess.run(init)\n", + " # train\n", + " for epoch in range(n_epochs):\n", + " X_batch, y_batch = next_batch(batch_size, n_steps)\n", + " sess.run(train_op, feed_dict={X: X_batch, y: y_batch})\n", + " if epoch % 100 == 0:\n", + " mse = sess.run(loss, feed_dict={X: X_batch, y: y_batch})\n", + " print(\"Epoch\", epoch, \"MSE\", mse)\n", + " \n", + " # generate\n", + " seq1 = [0.0 for i in range(n_steps)]\n", + " for itr in range(len(t) - n_steps):\n", + " X_batch = np.array(seq1[-n_steps:]).reshape(1, n_steps, 1)\n", + " y_pred = sess.run(outputs, feed_dict={X: X_batch})\n", + " seq1.append(y_pred[0, -1, 0])\n", + " \n", + " seq2 = [time_series(i * resolution + t_min + (t_max-t_min/3)) for i in range(n_steps)]\n", + " for itr in range(len(t) - n_steps):\n", + " X_batch = np.array(seq2[-n_steps:]).reshape(1, n_steps, 1)\n", + " y_pred = sess.run(outputs, feed_dict={X: X_batch})\n", + " seq2.append(y_pred[0, -1, 0])\n", + "\n", + "plt.figure(figsize=(11,4))\n", + "plt.subplot(121)\n", + "plt.plot(t, seq1, \"b-\")\n", + "plt.plot(t[:n_steps], seq1[:n_steps], \"b-\", linewidth=3)\n", + "plt.xlabel(\"Time\")\n", + "plt.ylabel(\"Value\")\n", + "\n", + "plt.subplot(122)\n", + "plt.plot(t, seq2, \"b-\")\n", + "plt.plot(t[:n_steps], seq2[:n_steps], \"b-\", linewidth=3)\n", + "plt.xlabel(\"Time\")\n", + "save_fig(\"creative_sequence_plot\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Deep RNN\n", + "### MultiRNNCell" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "tf.reset_default_graph()\n", + "\n", + "n_inputs = 2\n", + "n_units = 100\n", + "n_rnn_layers = 3\n", + "n_steps = 5\n", + "keep_prob = 0.5\n", + "\n", + "x = tf.placeholder(tf.float32, [None, n_steps, n_inputs])\n", + "cell = tf.contrib.rnn.MultiRNNCell([tf.contrib.rnn.BasicRNNCell(num_units=n_units) for _ in range(n_rnn_layers)])\n", + "outputs, states = tf.nn.dynamic_rnn(cell, x, dtype=tf.float32)\n", + "\n", + "init = tf.global_variables_initializer()" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "X_batch = np.random.rand(2, n_steps, n_inputs)\n", + "with tf.Session() as sess:\n", + " sess.run(init)\n", + " outputs_val, states_val = sess.run([outputs, states], feed_dict={x: X_batch})" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(2, 5, 100)\n" + ] + } + ], + "source": [ + "print(outputs_val.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3\n" + ] + } + ], + "source": [ + "print(len(states_val))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Dropout" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "tf.reset_default_graph()\n", + "\n", + "n_inputs = 1\n", + "n_units = 100\n", + "n_rnn_layers = 3\n", + "n_steps = 20\n", + "n_outputs = 1\n", + "\n", + "keep_prob = 0.8\n", + "learning_rate = 0.001\n", + "\n", + "def model(X, y, is_training=True):\n", + " if is_training:\n", + " cell_list = [tf.contrib.rnn.DropoutWrapper(tf.contrib.rnn.BasicRNNCell(num_units=n_units,), input_keep_prob=keep_prob)\n", + " for _ in range(n_rnn_layers)]\n", + " else:\n", + " cell_list = [tf.contrib.rnn.BasicRNNCell(num_units=n_units, reuse= not is_training) for _ in range(n_rnn_layers)]\n", + " \n", + " cell = tf.contrib.rnn.MultiRNNCell(cell_list)\n", + " rnn_outputs, states = tf.nn.dynamic_rnn(cell, X, dtype=tf.float32)\n", + " \n", + " stacked_rnn_outputs = tf.reshape(rnn_outputs, [-1, n_units])\n", + " stacked_outputs = tf.layers.dense(stacked_rnn_outputs, n_outputs)\n", + " outputs = tf.reshape(stacked_outputs, [-1, n_steps, n_outputs])\n", + " \n", + " loss = tf.reduce_sum(tf.square(outputs - y))\n", + " train_op = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)\n", + " \n", + " return outputs, loss, train_op\n", + "\n", + "X = tf.placeholder(tf.float32, [None, n_steps, n_inputs])\n", + "y = tf.placeholder(tf.float32, [None, n_steps, n_outputs])\n", + "with tf.variable_scope(\"model\", reuse=False):\n", + " t_outputs, loss, train_op = model(X, y)\n", + "\n", + "with tf.variable_scope(\"model\", reuse=True):\n", + " v_outputs, _, _ = model(X, y, is_training=False)\n", + "\n", + "init = tf.global_variables_initializer()" + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 0 MSE 28683.9\n", + "Epoch 100 MSE 5585.86\n", + "Epoch 200 MSE 4104.79\n", + "Epoch 300 MSE 2766.7\n", + "Epoch 400 MSE 2305.93\n", + "Epoch 500 MSE 2710.83\n", + "Epoch 600 MSE 1676.19\n", + "Epoch 700 MSE 1735.69\n", + "Epoch 800 MSE 1576.85\n", + "Epoch 900 MSE 2018.53\n", + "Epoch 1000 MSE 1770.96\n", + "Epoch 1100 MSE 1533.56\n", + "Epoch 1200 MSE 1374.3\n", + "Epoch 1300 MSE 1624.88\n", + "Epoch 1400 MSE 1252.66\n", + "Epoch 1500 MSE 1321.51\n", + "Epoch 1600 MSE 1600.19\n", + "Epoch 1700 MSE 1381.51\n", + "Epoch 1800 MSE 1419.25\n", + "Epoch 1900 MSE 1292.31\n" + ] + }, + { + "data": { + "image/png": "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\nJzNj2LBh+mYkRa+xEerqoLUV2trg0kvD8ksvDZ9bW8P6xsZo941TTqZrAAX4iOl+isD+/dCSMkTK\nvsSYWNOnQ2rj/y2HGE8sk33jlJNP8oejsREWL4aqKigpCfPFi3Pvr6mIxG/p0s6B+ogjOs8hrF+y\nJNp945TXQb6+Hqqr4fbbYffu8Nd09+7wubo6rO+vk046qV/73X///bz00ku9bygiA66+HubP7xys\nU7W0wLx58OtfR7tvnPI2yHfNj6WKIj/21FNP9Ws/BXmR3FVZCevWwYUXwp49ndft2ROWP/542C7K\nfeOUt0H+uuu6B/eu2trghhv6d/zKxL/UunXrmDlzJnV1dYwdO5aLL74YTyTgli1bxvjx46murmbp\n0qU89dRTPPDAA3zzm9+kpqaGxsZGfvzjHzN16lQmTZrEBRdcQGtrKwCXXHIJX//61znppJP40z/9\nU9as+aDL8+9973scd9xxTJo0iWXLlgHQ2NjInDlzmDJlCjNmzGBLriX+RPLAwoVQVgZDh0J7e5ha\nWz/4eejQsP7zn49231j1pQpONqdDVaF86aWXeq0+NGSIe0jQpJ+qqvpeJSlVRUWFu7s/9thjXlVV\n5a+99pp3dHT4iSee6OvXr/cdO3b4mDFjDlbzfO+999zd/Qtf+IKvXr364HF27Nhx8Odvf/vbfvPN\nNx/crq6uzjs6OvzFF1/00aNHu7v7Qw895J/61Ke8paXF3d3feecdd3c/7bTTfOvWre7u/vTTT/us\nWbMO+5r6cl9FCtnLL4eqjo8+6t7e7v7MM+5nnBHm7e3uv/lNWP/yy9Humw30sQplztau6U1zc7Tb\npXPCCScwfPhwAGpqati+fTsnnngigwcP5rLLLmP+/PnMnz//kPu+8MILXHXVVezcuZPm5mZmz559\ncN2nP/1pSkpKGD9+PH/8YxjX4pFHHuGLX/wi5eXlABx11FE0Nzfz1FNPsWDBgoP77ku+2heRPhs9\nGtasCXHhyivh+uvD4+DUqfCNb8App4T1h2rUlMm+ccrbdE1f815R5MeOSHl9XlpaSnt7O4MGDeJ3\nv/sddXV13H///cyZM+eQ+15yySWsXLmS559/nquvvrpTXfXU43qawVsOHDjA0KFD2bRp08Fp8+bN\nmV+YSBGaOxfGj4e9e2HIkFArr7Iy5NXHjw/rs7FvXPI2yCfzY+lkMz/W3NzMrl27OPvss7nxxhvZ\n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\nAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "n_epochs = 2000\n", + "batch_size = 128\n", + "\n", + "with tf.Session() as sess:\n", + " sess.run(init)\n", + " for epoch in range(n_epochs):\n", + " X_batch, y_batch = next_batch(batch_size, n_steps)\n", + " sess.run(train_op, feed_dict={X: X_batch, y: y_batch})\n", + " if epoch % 100 == 0:\n", + " mse = sess.run(loss, feed_dict={X: X_batch, y: y_batch})\n", + " print(\"Epoch\", epoch, \"MSE\", mse)\n", + " \n", + " # Test\n", + " X_new = time_series(np.array(t_instance[:-1].reshape(-1, n_steps, n_inputs)))\n", + " y_pred = sess.run(v_outputs, feed_dict={X: X_new})\n", + " \n", + " plt.title(\"Testing the model\", fontsize=14)\n", + " plt.plot(t_instance[:-1], time_series(t_instance[:-1]), \"bo\", markersize=10, label=\"instance\")\n", + " plt.plot(t_instance[1:], time_series(t_instance[1:]), \"w*\", markersize=10, label=\"target\")\n", + " plt.plot(t_instance[1:], y_pred[0,:,0], \"r.\", markersize=10, label=\"prediction\")\n", + " plt.legend(loc=\"upper left\")\n", + " plt.xlabel(\"Time\")\n", + " plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 106, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "tf.reset_default_graph()\n", + "\n", + "n_inputs = 1\n", + "n_units = 100\n", + "n_rnn_layers = 3\n", + "n_steps = 20\n", + "n_outputs = 1\n", + "\n", + "keep_prob = 0.5\n", + "learning_rate = 0.001\n", + "\n", + "def model(X, y, keep_prob_t):\n", + " \n", + " cell_list = [tf.contrib.rnn.DropoutWrapper(tf.contrib.rnn.BasicRNNCell(num_units=n_units,), input_keep_prob=keep_prob_t)\n", + " for _ in range(n_rnn_layers)]\n", + " \n", + " cell = tf.contrib.rnn.MultiRNNCell(cell_list)\n", + " rnn_outputs, states = tf.nn.dynamic_rnn(cell, X, dtype=tf.float32)\n", + " \n", + " stacked_rnn_outputs = tf.reshape(rnn_outputs, [-1, n_units])\n", + " stacked_outputs = tf.layers.dense(stacked_rnn_outputs, n_outputs)\n", + " outputs = tf.reshape(stacked_outputs, [-1, n_steps, n_outputs])\n", + " \n", + " loss = tf.reduce_sum(tf.square(outputs - y))\n", + " train_op = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)\n", + " \n", + " return outputs, loss, train_op\n", + "\n", + "X = tf.placeholder(tf.float32, [None, n_steps, n_inputs])\n", + "y = tf.placeholder(tf.float32, [None, n_steps, n_outputs])\n", + "keep_prob_t = tf.placeholder(tf.float32)\n", + "\n", + "outputs, loss, train_op = model(X, y, keep_prob_t)\n", + "\n", + "init = tf.global_variables_initializer()\n", + "saver = tf.train.Saver()" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 0 MSE 16760.1\n", + "Epoch 100 MSE 4765.84\n", + "Epoch 200 MSE 3794.69\n", + "Epoch 300 MSE 3385.63\n", + "Epoch 400 MSE 4468.75\n", + "Epoch 500 MSE 3069.24\n", + "Epoch 600 MSE 2526.14\n", + "Epoch 700 MSE 2431.3\n", + "Epoch 800 MSE 1855.84\n", + "Epoch 900 MSE 2820.45\n", + "Epoch 1000 MSE 3579.5\n", + "Epoch 1100 MSE 2346.72\n", + "Epoch 1200 MSE 2487.6\n", + "Epoch 1300 MSE 2309.52\n", + "Epoch 1400 MSE 2915.64\n", + "Epoch 1500 MSE 2728.46\n", + "Epoch 1600 MSE 2031.27\n", + "Epoch 1700 MSE 1942.66\n", + "Epoch 1800 MSE 2280.94\n", + "Epoch 1900 MSE 2746.33\n" + ] + }, + { + "data": { + "image/png": "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\njz4agOeee45JkyZx0EEHATBz5kzeeOMNIHQfnDpa1CeffEJLFH0gi4j0oGT7k8+XJUuW0NzczPPP\nP09lZSXDhg3b013wwIEDMzrG7t27efbZZxkwYEAuiyoiso+S7rsmV1K7C968eTOf/vSnqays5Ikn\nnuDtt9/ucp/x48fz5JNP8vHHH9Pe3s5vfvObPetOPvlkbrnllj2fu+uWWEQkagryXTj44IOZMGEC\no0ePZs2aNaxevZpx48axZMmSbrsL/vznP88PfvADjjrqKE488URqa2s58MADAbj55ptZvXo1dXV1\n1NbWcttttwFw+umnc//99+vFq4jkTEl3NVxsWlpaqK6upr29nRkzZjB79mxmzJhR6GLtUar3VUT2\nVRZdDRebq666ivr6ekaPHs3w4cM566yzCl0kESlzevEaoeQoTiIixUJP8iIiMaYgLyIFo3Fac09B\nXkQKorER6urgjjtgyhSYMQMmTw6f6+rCesmegryI5J3Gac0fBfk8qU6MYPD+++/T0NCQdtsbb7yR\n1tbWPZ9PPfVUNm3alNPyieRTcpxW9zAdc0xYnhyn1T2sb2srbDnjIB5BftcuePhhuPrqMN+1K0+n\n7f15Pve5z7Fs2bK023QO8o888giDBw/u9blEipXGac2f0g/yu3bBKafAeefBlVeG+SmnZB3o169f\nz8iRI7nwwgupq6ujoaGB1tZWhg0bxsKFCzn22GNZunQpTU1NTJ06lbFjxzJx4kTWJoaIX7duHV/7\n2tcYP348P/rRjzocd/To0Ymi72L+/PmMHj2auro6brnlFm6++Wbef/99pkyZwpQpUwAYNmwYGzZs\nAOD6669n9OjRjB49mhtvvHHPMQ877DC++c1vMmrUKE4++WS2dR4XTaSIaJzWPMqkq8pcTll3NfzQ\nQ+7V1clveGGqrg7Ls7Bu3ToH/KmnnnJ394svvtivvfZaHzp0qF9zzTV7tjv++OP9jTfecHf3Z599\n1qdMmeLu7qeffrrfdddd7u6+aNEiHzhw4J7jJrsxvvXWW/3ss8/2trY2d3ffuHGju7sPHTrUm5ub\n95wj+Xn16tU+evRob2lp8S1btnhtba3/6U9/8nXr1nm/fv38hRdecHf3mTNn+t13373PNamrYSkW\ngwaF/6qnnebe2tpxXWtrWA7uNTWFKV8pIMOuhkv/Sf6FF/Z9HNi6FRKdgGXjC1/4AhMmTABg1qxZ\n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\nFxGJsf8PnogMn0CiSycAAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "n_epochs = 2000\n", + "batch_size = 50\n", + "\n", + "with tf.Session() as sess:\n", + " sess.run(init)\n", + " for epoch in range(n_epochs):\n", + " X_batch, y_batch = next_batch(batch_size, n_steps)\n", + " sess.run(train_op, feed_dict={X: X_batch, y: y_batch, keep_prob_t: keep_prob})\n", + " if epoch % 100 == 0:\n", + " mse = sess.run(loss, feed_dict={X: X_batch, y: y_batch, keep_prob_t: keep_prob})\n", + " print(\"Epoch\", epoch, \"MSE\", mse)\n", + " # Test\n", + " \n", + " X_new = time_series(np.array(t_instance[:-1].reshape(-1, n_steps, n_inputs)))\n", + " y_pred = sess.run(outputs, feed_dict={X: X_new, keep_prob_t: 1.0})\n", + " \n", + " plt.title(\"Testing the model\", fontsize=14)\n", + " plt.plot(t_instance[:-1], time_series(t_instance[:-1]), \"bo\", markersize=10, label=\"instance\")\n", + " plt.plot(t_instance[1:], time_series(t_instance[1:]), \"w*\", markersize=10, label=\"target\")\n", + " plt.plot(t_instance[1:], y_pred[0,:,0], \"r.\", markersize=10, label=\"prediction\")\n", + " plt.legend(loc=\"upper left\")\n", + " plt.xlabel(\"Time\")\n", + " plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### LSTM" + ] + }, + { + "cell_type": "code", + "execution_count": 109, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "tf.reset_default_graph()\n", + "\n", + "n_steps = 28\n", + "n_inputs = 28\n", + "n_units = 150\n", + "n_outputs = 10\n", + "n_lstm_layers = 3\n", + "\n", + "learning_rate = 0.001\n", + "\n", + "x = tf.placeholder(tf.float32, [None, n_steps, n_inputs])\n", + "y = tf.placeholder(tf.int32, [None,])\n", + "\n", + "with tf.variable_scope(\"LSTM\", initializer=tf.contrib.layers.variance_scaling_initializer()):\n", + " cell_list = [tf.contrib.rnn.BasicLSTMCell(num_units=n_units, forget_bias=0.0) for _ in range(n_lstm_layers)]\n", + " cell = tf.contrib.rnn.MultiRNNCell(cell_list)\n", + " outputs, states = tf.nn.dynamic_rnn(cell, x, dtype=tf.float32)\n", + " \n", + "top_lstm_layer_h = states[-1][1]\n", + "\n", + "logits = tf.layers.dense(top_lstm_layer_h, n_outputs) # fully connected layer\n", + "entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=y)\n", + "loss = tf.reduce_mean(entropy)\n", + "train_op = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)\n", + "\n", + "correct = tf.nn.in_top_k(logits, y, 1)\n", + "accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))\n", + "\n", + "init = tf.global_variables_initializer()" + ] + }, + { + "cell_type": "code", + "execution_count": 110, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(LSTMStateTuple(c=, h=), LSTMStateTuple(c=, h=), LSTMStateTuple(c=, h=))\n" + ] + } + ], + "source": [ + "print(states)" + ] + }, + { + "cell_type": "code", + "execution_count": 111, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Tensor(\"LSTM/rnn/while/Exit_7:0\", shape=(?, 150), dtype=float32)\n" + ] + } + ], + "source": [ + "print(top_lstm_layer_h)" + ] + }, + { + "cell_type": "code", + "execution_count": 112, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 Train accuracy: 0.98 Test accuracy: 0.9404\n", + "1 Train accuracy: 1.0 Test accuracy: 0.9815\n", + "2 Train accuracy: 1.0 Test accuracy: 0.978\n", + "3 Train accuracy: 1.0 Test accuracy: 0.9804\n", + "4 Train accuracy: 1.0 Test accuracy: 0.9801\n", + "5 Train accuracy: 1.0 Test accuracy: 0.9895\n", + "6 Train accuracy: 1.0 Test accuracy: 0.9839\n", + "7 Train accuracy: 1.0 Test accuracy: 0.9886\n", + "8 Train accuracy: 1.0 Test accuracy: 0.9907\n", + "9 Train accuracy: 1.0 Test accuracy: 0.9859\n", + "10 Train accuracy: 1.0 Test accuracy: 0.9914\n", + "11 Train accuracy: 0.98 Test accuracy: 0.9888\n", + "12 Train accuracy: 1.0 Test accuracy: 0.9839\n", + "13 Train accuracy: 1.0 Test accuracy: 0.99\n", + "14 Train accuracy: 1.0 Test accuracy: 0.9881\n", + "15 Train accuracy: 1.0 Test accuracy: 0.9887\n", + "16 Train accuracy: 1.0 Test accuracy: 0.9894\n", + "17 Train accuracy: 1.0 Test accuracy: 0.9906\n", + "18 Train accuracy: 1.0 Test accuracy: 0.9915\n", + "19 Train accuracy: 1.0 Test accuracy: 0.9868\n" + ] + } + ], + "source": [ + "n_epochs = 20\n", + "\n", + "with tf.Session() as sess:\n", + " sess.run(init)\n", + " for epoch in range(n_epochs):\n", + " for itr in range(mnist.train.num_examples // batch_size):\n", + " X_batch, y_batch = mnist.train.next_batch(batch_size)\n", + " X_batch = X_batch.reshape((-1, n_steps, n_inputs))\n", + " sess.run(train_op, feed_dict={x: X_batch, y: y_batch})\n", + " acc_train = accuracy.eval(feed_dict={x: X_batch, y: y_batch})\n", + " acc_test = accuracy.eval(feed_dict={x: X_test, y: y_test})\n", + " print(epoch, \"Train accuracy:\", acc_train, \"Test accuracy:\", acc_test)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Distributing layers across devices" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# the implemention of tf.contrib.rnn.DeviceWrapper\n", + "class DeviceCellWrapper(tf.contrib.rnn.RNNCell):\n", + " def __init__(self, device, cell):\n", + " self._cell = cell\n", + " self._device = device\n", + " \n", + " @property\n", + " def state_size(self):\n", + " return self._cell.state_size\n", + " \n", + " @property\n", + " def output_size(self):\n", + " return self._cell.output_size\n", + " \n", + " def zero_state(self, batch_size, dtype=tf.float32):\n", + " with tf.name_scope(type(self).__name__ + \"ZeroState\", values=[batch_size]):\n", + " return self._cell.zero_state(batch_size, dtype)\n", + " \n", + " def __call__(self, inputs, state, scope=None):\n", + " with tf.device(self._device):\n", + " return self._cell(inputs, state, scope=scope)" + ] + }, + { + "cell_type": "code", + "execution_count": 114, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "tf.reset_default_graph()\n", + "\n", + "n_inputs = 5\n", + "n_units = 100\n", + "devices = [\"/cpu:0\"] * 5\n", + "n_steps = 20\n", + "\n", + "x = tf.placeholder(tf.float32, [None, n_steps, n_inputs])\n", + "lstm_cells = [DeviceCellWrapper(d, tf.contrib.rnn.BasicLSTMCell(num_units=n_units))\n", + " for d in devices]\n", + "cell = tf.contrib.rnn.MultiRNNCell(lstm_cells)\n", + "outputs, states = tf.nn.dynamic_rnn(cell, x, dtype=tf.float32)\n", + "\n", + "init = tf.global_variables_initializer()" + ] + }, + { + "cell_type": "code", + "execution_count": 120, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(2, 20, 100)\n", + "[[[ 1.10517049e-05 -3.39324652e-06 1.88815375e-06 ..., 2.07342018e-05\n", + " 3.01883642e-06 -2.07689263e-05]\n", + " [ 3.81280479e-05 -1.45351160e-05 6.74469720e-06 ..., 8.08613331e-05\n", + " 1.27205421e-05 -8.34117818e-05]\n", + " [ 8.20077476e-05 -3.77131146e-05 1.54183545e-05 ..., 1.95936620e-04\n", + " 3.81563914e-05 -2.11727267e-04]\n", + " ..., \n", + " [ -2.00475683e-03 5.37709100e-04 1.62039138e-03 ..., 1.68269128e-03\n", + " 8.14274128e-04 -6.40866486e-03]\n", + " [ -2.47456320e-03 1.01784908e-03 1.95362838e-03 ..., 1.44464616e-03\n", + " 3.96985182e-04 -6.36696117e-03]\n", + " [ -2.93949479e-03 1.55080645e-03 2.30732700e-03 ..., 1.21466152e-03\n", + " -9.47825174e-05 -6.24832604e-03]]\n", + "\n", + " [[ 1.12432090e-05 8.80935374e-07 5.98191309e-06 ..., 1.70006078e-05\n", + " -3.92921083e-06 -8.98602048e-06]\n", + " [ 4.35743132e-05 4.29972516e-07 2.38444045e-05 ..., 8.29850906e-05\n", + " -1.44983460e-05 -4.59686889e-05]\n", + " [ 9.71345289e-05 -8.25025108e-06 5.86029855e-05 ..., 2.20897273e-04\n", + " -2.93557896e-05 -1.30734494e-04]\n", + " ..., \n", + " [ -1.59456290e-03 1.82719575e-03 1.26134360e-03 ..., -1.34795671e-04\n", + " -1.10723753e-03 -2.64281454e-03]\n", + " [ -1.86645042e-03 2.46469839e-03 1.37204758e-03 ..., -5.05617587e-04\n", + " -1.48592005e-03 -2.31303484e-03]\n", + " [ -2.13730359e-03 3.17968265e-03 1.51283597e-03 ..., -8.43492569e-04\n", + " -1.91095355e-03 -1.90485246e-03]]]\n", + "5\n", + "(2, 100)\n" + ] + } + ], + "source": [ + "with tf.Session() as sess:\n", + " sess.run(init)\n", + " o, s = sess.run([outputs, states], feed_dict={x: np.random.rand(2, n_steps, n_inputs)})\n", + " print(o.shape)\n", + " print(o)\n", + " print(len(s))\n", + " print(s[-1][-1].shape)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Embeddings" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Get the data" + ] + }, + { + "cell_type": "code", + "execution_count": 121, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import urllib.request\n", + "import zipfile\n", + "import os\n", + "\n", + "WORDS_PATH = \"datasets/words\"\n", + "WORDS_URL = 'http://mattmahoney.net/dc/text8.zip'\n", + "\n", + "def fetch_words_data(words_url=WORDS_URL, words_path=WORDS_PATH):\n", + " os.makedirs(words_path, exist_ok=True)\n", + " zip_path = os.path.join(words_path, \"words.zip\")\n", + " if not os.path.exists(zip_path):\n", + " urllib.request.urlretrieve(words_url, zip_path)\n", + " with zipfile.ZipFile(zip_path) as f:\n", + " data = f.read(f.namelist()[0])\n", + " return data.decode(\"ascii\").split()" + ] + }, + { + "cell_type": "code", + "execution_count": 122, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "words = fetch_words_data()" + ] + }, + { + "cell_type": "code", + "execution_count": 123, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['anarchism', 'originated', 'as', 'a', 'term']\n" + ] + } + ], + "source": [ + "print(words[:5])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Bulid the dictionary" + ] + }, + { + "cell_type": "code", + "execution_count": 124, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from collections import Counter\n", + "\n", + "vocb_size = 50000\n", + "\n", + "vocabulary = [(\"UNK\", None)] + Counter(words).most_common(vocb_size - 1)\n", + "vocabulary = np.array([w for w, _ in vocabulary])\n", + "word_to_idx = {w: id for id, w in enumerate(vocabulary)}\n", + "data = np.array([word_to_idx.get(w, 0) for w in words])" + ] + }, + { + "cell_type": "code", + "execution_count": 128, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "('anarchism originated as a term of abuse first used',\n", + " array([5234, 3081, 12, 6, 195, 2, 3134, 46, 59]))" + ] + }, + "execution_count": 128, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\" \".join(words[:9]), data[:9]" + ] + }, + { + "cell_type": "code", + "execution_count": 127, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "17005207 50000\n" + ] + } + ], + "source": [ + "print(len(data), len(word_to_idx))" + ] + }, + { + "cell_type": "code", + "execution_count": 129, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'cycles originated as a term of abuse first used'" + ] + }, + "execution_count": 129, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\" \".join([vocabulary[word_index] for word_index in [5241, 3081, 12, 6, 195, 2, 3134, 46, 59]])" + ] + }, + { + "cell_type": "code", + "execution_count": 130, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "('culottes', 0)" + ] + }, + "execution_count": 130, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "words[24], data[24]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Generate batch" + ] + }, + { + "cell_type": "code", + "execution_count": 131, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import random\n", + "from collections import deque\n", + "\n", + "def generate_batch(batch_size, num_skips, skip_window):\n", + " global data_index\n", + " assert batch_size % num_skips == 0\n", + " assert num_skips <= 2 * skip_window\n", + " batch = np.ndarray(shape=(batch_size), dtype=np.int32)\n", + " labels = np.ndarray(shape=(batch_size, 1), dtype=np.int32)\n", + " span = 2 * skip_window + 1 # [ skip_window target skip_window ]\n", + " buffer = deque(maxlen=span)\n", + " for _ in range(span):\n", + " buffer.append(data[data_index])\n", + " data_index = (data_index + 1) % len(data)\n", + " for i in range(batch_size // num_skips):\n", + " target = skip_window # target label at the center of the buffer\n", + " targets_to_avoid = [ skip_window ]\n", + " for j in range(num_skips):\n", + " while target in targets_to_avoid:\n", + " target = random.randint(0, span - 1)\n", + " targets_to_avoid.append(target)\n", + " batch[i * num_skips + j] = buffer[skip_window]\n", + " labels[i * num_skips + j, 0] = buffer[target]\n", + " buffer.append(data[data_index])\n", + " data_index = (data_index + 1) % len(data)\n", + " return batch, labels" + ] + }, + { + "cell_type": "code", + "execution_count": 132, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "data_index=0\n", + "batch, labels = generate_batch(8, 2, 1)" + ] + }, + { + "cell_type": "code", + "execution_count": 133, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[3081 3081 12 12 6 6 195 195] ['originated', 'originated', 'as', 'as', 'a', 'a', 'term', 'term']\n" + ] + } + ], + "source": [ + "print(batch, [vocabulary[idx] for idx in batch])" + ] + }, + { + "cell_type": "code", + "execution_count": 135, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 12]\n", + " [5234]\n", + " [ 6]\n", + " [3081]\n", + " [ 12]\n", + " [ 195]\n", + " [ 6]\n", + " [ 2]] ['as', 'anarchism', 'a', 'originated', 'as', 'term', 'a', 'of']\n" + ] + } + ], + "source": [ + "print(labels, [vocabulary[idx] for idx in labels[:, 0]])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Build the model" + ] + }, + { + "cell_type": "code", + "execution_count": 136, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "batch_size = 128\n", + "embedding_size = 128 # dimension of the embedding vector\n", + "skip_window = 1 # how many words to consider left and right\n", + "num_skips = 2 # how many times to reuse an input to generate a label\n", + "\n", + "# validation set\n", + "valid_size = 16 # Random set of words to evaluate similarity on\n", + "valid_window = 100 # Only pick dev samples in the head of the distribution.\n", + "valid_examples = np.random.choice(valid_window, valid_size, replace=False)\n", + "\n", + "num_sampled = 64 # Number of negative examples to sample.\n", + "\n", + "learning_rate = 0.01" + ] + }, + { + "cell_type": "code", + "execution_count": 141, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "tf.reset_default_graph()\n", + "\n", + "# Input data.\n", + "train_inputs = tf.placeholder(tf.int32, shape=[batch_size])\n", + "train_labels = tf.placeholder(tf.int32, shape=[batch_size, 1])\n", + "valid_dataset = tf.constant(valid_examples, dtype=tf.int32)\n", + "\n", + "# Look up embeddings for inputs.\n", + "init_embeddings = tf.random_uniform([vocb_size, embedding_size], -1.0, 1.0)\n", + "embeddings = tf.Variable(init_embeddings)\n", + "embed = tf.nn.embedding_lookup(embeddings, train_inputs)\n", + "\n", + "# Construct the variables for the NCE loss\n", + "nce_weights = tf.Variable(\n", + " tf.truncated_normal([vocb_size, embedding_size],\n", + " stddev=1.0 / np.sqrt(embedding_size)))\n", + "nce_biases = tf.Variable(tf.zeros([vocb_size]))\n", + "\n", + "# Compute the average NCE loss for the batch.\n", + "# tf.nce_loss automatically draws a new sample of the negative labels each\n", + "# time we evaluate the loss.\n", + "loss = tf.reduce_mean(\n", + " tf.nn.nce_loss(nce_weights, nce_biases, train_labels, embed,\n", + " num_sampled, vocb_size))\n", + "\n", + "# Construct the Adam optimizer\n", + "train_op = tf.train.AdamOptimizer(learning_rate).minimize(loss)\n", + "\n", + "# Compute the cosine similarity between minibatch examples and all embeddings.\n", + "norm = tf.sqrt(tf.reduce_sum(tf.square(embeddings), axis=1, keep_dims=True))\n", + "normalized_embeddings = embeddings / norm\n", + "valid_embeddings = tf.nn.embedding_lookup(normalized_embeddings, valid_dataset)\n", + "similarity = tf.matmul(valid_embeddings, normalized_embeddings, transpose_b=True)\n", + "\n", + "# Add variable initializer.\n", + "init = tf.global_variables_initializer()" + ] + }, + { + "cell_type": "code", + "execution_count": 144, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Iteration: 0\tAverage loss at step 0 : 314.16708374\n", + "Nearest to its: tbs, durham, monographs, increased, giles, elevations, spotted, conciliation,\n", + "Nearest to are: killed, grappling, message, idealists, stamps, lighters, counterbalanced, enya,\n", + "Nearest to zero: trunks, buzz, gangrene, intrusions, fishing, dealing, orchard, obtains,\n", + "Nearest to time: freedoms, casual, keralite, karenina, pouring, blogger, subgroup, disappeared,\n", + "Nearest to b: hay, reagan, ligny, columbian, cripps, beja, asking, lancers,\n", + "Nearest to united: destruction, watches, were, filmfare, earthly, strived, kaolinite, discharges,\n", + "Nearest to new: ciphertexts, kwajalein, maccabees, abba, calculated, impaired, joked, loxodonta,\n", + "Nearest to than: cen, say, boca, rms, discusses, tilt, wasn, trailed,\n", + "Nearest to about: swell, peninsulas, zaghawa, predication, fragments, cries, lombards, reliable,\n", + "Nearest to s: molecular, rhymes, housework, incubation, wr, perform, certificates, tirelessly,\n", + "Nearest to all: malleus, asiatic, financially, oxidise, naci, quotients, literally, outsider,\n", + "Nearest to which: satisfactory, severely, matthews, retrial, laterally, tennis, histoire, dum,\n", + "Nearest to state: nostrils, workout, architects, methodist, neberg, unobservable, faster, barbaric,\n", + "Nearest to or: invaluable, plekhanov, amir, fran, larry, rhodesian, violins, mobs,\n", + "Nearest to years: arose, yamato, laotian, connectedness, kuhn, sundial, corrode, inaccurate,\n", + "Nearest to UNK: paedophilia, cadr, tutsi, girardeau, ponens, syllogism, stripping, rivaled,\n", + "Iteration: 2000\tAverage loss at step 2000 : 133.200406511\t\t\t\n", + "Iteration: 4000\tAverage loss at step 4000 : 63.4152127714\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n", + "Iteration: 6000\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tAverage loss at step 6000 : 41.7139164894\n", + "Iteration: 8000\tAverage loss at step \t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t 8000 : 31.0701406903\n", + "Iteration: 10000\tAverage loss at step 10000 : 25.911286181\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n", + "Nearest to its: the, damon, advertising, bhfiann, photosynthesis, clinic, bayan, plant,\n", + "Nearest to are: is, have, agnetha, tarkovsky, were, and, gide, aardvarks,\n", + "Nearest to zero: two, five, nine, six, four, eight, three, seven,\n", + "Nearest to time: topalov, confiscated, sarcoma, steppe, nen, decades, condoms, alif,\n", + "Nearest to b: foresee, ankh, and, ge, dopamine, sidebands, var, appropriation,\n", + "Nearest to united: meyer, states, averaging, identity, branden, bowed, material, hellenic,\n", + "Nearest to new: grimaldi, populated, monsieur, hypothetical, gravitation, priests, amy, capitalists,\n", + "Nearest to than: much, dennett, this, admitting, withdrawal, recruiting, mich, sedgwick,\n", + "Nearest to about: bj, male, appealed, apocalypse, utility, performed, pregnancy, cluny,\n", + "Nearest to s: his, the, of, amoebae, altaic, vocal, nen, collapse,\n", + "Nearest to all: legs, cosmonauts, enthusiasm, dissimilar, asperger, appended, proving, damascus,\n", + "Nearest to which: the, a, unarable, parodied, photosynthesis, snowball, argentine, tezuka,\n", + "Nearest to state: theodor, coherence, tempered, amhr, debt, criticised, for, observing,\n", + "Nearest to or: and, android, for, australopithecus, seo, lay, morpork, of,\n", + "Nearest to years: decades, defenders, survival, plebiscite, ivb, sowed, fremantle, syndrome,\n", + "Nearest to UNK: and, six, the, bogus, ginsberg, one, foul, bj,\n" + ] + } + ], + "source": [ + "num_steps = 10001\n", + "\n", + "with tf.Session() as sess:\n", + " sess.run(init)\n", + "\n", + " average_loss = 0\n", + " for step in range(num_steps):\n", + " print(\"\\rIteration: {}\".format(step), end=\"\\t\")\n", + " batch_inputs, batch_labels = generate_batch(batch_size, num_skips, skip_window)\n", + " feed_dict = {train_inputs : batch_inputs, train_labels : batch_labels}\n", + "\n", + " # We perform one update step by evaluating the training op (including it\n", + " # in the list of returned values for session.run()\n", + " _, loss_val = sess.run([train_op, loss], feed_dict=feed_dict)\n", + " average_loss += loss_val\n", + "\n", + " if step % 2000 == 0:\n", + " if step > 0:\n", + " average_loss /= 2000\n", + " # The average loss is an estimate of the loss over the last 2000 batches.\n", + " print(\"Average loss at step \", step, \": \", average_loss)\n", + " average_loss = 0\n", + "\n", + " # Note that this is expensive (~20% slowdown if computed every 500 steps)\n", + " if step % 10000 == 0:\n", + " sim = similarity.eval()\n", + " for i in range(valid_size):\n", + " valid_word = vocabulary[valid_examples[i]]\n", + " top_k = 8 # number of nearest neighbors\n", + " nearest = (-sim[i, :]).argsort()[1:top_k+1]\n", + " log_str = \"Nearest to %s:\" % valid_word\n", + " for k in range(top_k):\n", + " close_word = vocabulary[nearest[k]]\n", + " log_str = \"%s %s,\" % (log_str, close_word)\n", + " print(log_str)\n", + "\n", + " final_embeddings = normalized_embeddings.eval()" + ] + }, + { + "cell_type": "code", + "execution_count": 145, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "np.save(\"./my_final_embeddings.npy\", final_embeddings)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Plot the embeddings" + ] + }, + { + "cell_type": "code", + "execution_count": 150, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def plot_with_labels(low_dim_embs, labels):\n", + " assert low_dim_embs.shape[0] >= len(labels), \"More labels than embeddings\"\n", + " plt.figure(figsize=(18, 18)) #in inches\n", + " for i, label in enumerate(labels):\n", + " x, y = low_dim_embs[i,:]\n", + " plt.scatter(x, y)\n", + " plt.annotate(label,\n", + " xy=(x, y),\n", + " xytext=(5, 2),\n", + " textcoords='offset points',\n", + " ha='right',\n", + " va='bottom')\n", + " plt.savefig(\"./1.png\",format=\"png\", dpi=300)" + ] + }, + { + "cell_type": "code", + "execution_count": 151, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABB4AAAP4CAYAAAB6HD8iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3XlclOX+//HXgMjignrQr2geUVNRYUAEFdFESbQSNZfK\n7ISVqdlidvSklUlq24mva5q/Vluw3BeiTh5Qv8cFRTZxA0mbNMUyFRIEZZnfHx4mSU1RhgF8Px+P\nHjrXvX3uybB5z3V/LoPZbEZERERERERExBrsbF2AiIiIiIiIiNRcCh5ERERERERExGoUPIiIiIiI\niIiI1Sh4EBERERERERGrUfAgIiIiIiIiIlaj4EFERERERERErEbBg4iIiIiIiIhYjYIHERERERER\nEbEaBQ8iIiIiIiIiYjW1bF3An3FzczN7eHjYugwRERERERER+YOkpKRfzWZz4+vtV6WDBw8PDxIT\nE21dhoiIiIiIiIj8gcFg+PFG9tOjFiIiIiIiIiJiNQoeRERERERERMRqFDyIiIiIiIiIiNUoeBAR\nERERERERq1HwICIiIiIiIiJWo+BBRERERERERKxGwYOIiIiIiIiIWI2CBxERERERERGxGgUPIiIi\nIiIiImI1Ch5ERERERERExGoUPIiIiIiIiIiI1Sh4EBERERERERGrUfAgIiIiIiIiIlaj4EFERERE\nRERErEbBg4iIiIiIiIhYjYIHEREREREREbEaBQ8iIiIiIiIiYjUKHkRERERERETEahQ8iIiIiIiI\niIjVKHgQEREREREREatR8CAiIiIiIiIiVqPgQURERERERESsRsGDiIiIiIiIiFiNggcRERERERER\nsRoFDyIiIiIiIiJiNQoeRERERERERMRqFDyIiIiIiIiIiNUoeBARERERERERq1HwICIiIiIiIiJW\no+BBRERERERERKxGwYOIiIiIiIiIWI2CBxERERERERGxGgUPIiIiIiIiImI1FRY8GAwGR4PB8JHB\nYPjRYDCcMxgMqQaD4Z7LtocYDIZ0g8Fw3mAwbDYYDC0r6toiIiIiIiIiUjVV5IyHWsAxoDfgCrwC\nrDAYDB4Gg8ENWANMBxoBicDyCry2iIiIyG1n3rx5nD9/3tZliIiI/KkKCx7MZnOe2WyOMJvNJrPZ\nXGI2m78GfgC6AEOB/WazeaXZbC4AIgAfg8HgWVHXFxEREbndKHgQEZHqoJa1TmwwGP4HaAfsB54C\n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\nnj59urRq1apqG9/z6siRI5KOjo6Uk5MjSZIktW3bVvq///s/SZIkadu2bZKVlZVkaWkpzZ49Wz6m\n6GdRpFWrVtLNmzcllUol+fr6SrNmzaq+C6iA9Iw9UmSkm3QkpI0UGekmpWfU7HsIQRA0ATFSOT7b\n13hw4XH/ROBBEMonKSlJatu2rXTz5k1JkiTp9u3bUs+ePaXNmzdLkiRJ33zzjdSnTx9JktQBgiFD\nhkgqlUras2eP1KBBAykhIUEqLCyU7O3t5Q9tgPT9999LkiRJH330kfTuu+9KkiRJt27dks87f/58\nKSAgQO534MCBUmFhoXT27FmpTZs2kiRJUnh4uHzurKwsydTUVMrPz6/qp6SEy5cvS+bm5tKkSZMk\npVIpbd68ucw3ZrNnz5bs7e0lHx8f6eTJk1Lnzp0lMzMzae/evXJfbm5ukp2dnWRnZycdO3ZMkiRJ\nCgsLkzp37iwNGDBAeuONN6Rhw4ZJKpWq2q/1ZXX58mXpX//6l/x4xYoV0tKlSyU9PT3J1tZW/mdu\nbi5JkiQtW7ZMWrdunTRr1ixp586dUvfu3aWIiAhp0KBBNXUJwgsg5/R1Kf2Tk9KVOUel9E9OSjmn\nr9f0kMotPj5e+uyzz6TFixdLn332mRQfH//MfRZ92D148KDk7Ows3b17V5IkSfrzzz+l69evS7Gx\nsZK1tbV0//596c6dO9K//vUvEXioBrtP/yl1+iREMp2zX+r0SYi0+/SfNT0kQRCeU+UNPIilFoLw\nAggNDWXQoEFyLe7GjRsTFRXFsGHDABg5ciSRkZHy/r169ZIztzdr1kwjq3tR5nItLS15evCIESPk\n45OSknB3d8fa2prAwEDOnv2nKm7fvn3R0tLCwsKC69evA9C5c2dSU1O5efMm27dvZ8CAAejoVGp6\nmXI7f/48o0aN4ueff2bhwoVlZv329PQkNjaWBg0asGDBAg4fPszu3btZtGgRAE2bNuXw4cOcPn2a\noKAgpk2bJp/jzJkzrFmzhuTkZC5dusSxY8dq5FpfVo8mxMvMzKRRo0bExcXJ/86dOweol1RERERw\n6tQp3nrrLbKysggPD8fd3b2mhi885+6duUHWrlS5SkFh1gOydqVy78yNGh7ZkyUkJBAcHEx2djYA\n2dnZBAcHk5CQUCn9d+3alWHDhtGxY0esra0ZOHAgd+/exd7eniFDhqBUKhkwYID4/1cN9py5yrxd\n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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from sklearn.manifold import TSNE\n", + "\n", + "tsne = TSNE(perplexity=30, n_components=2, init='pca', n_iter=5000)\n", + "plot_only = 500\n", + "low_dim_embs = tsne.fit_transform(final_embeddings[:plot_only,:])\n", + "labels = [vocabulary[i] for i in range(plot_only)]\n", + "plot_with_labels(low_dim_embs, labels)\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/results/654362565405877642.jpg b/results/654362565405877642.jpg new file mode 100644 index 0000000..5fbcede Binary files /dev/null and b/results/654362565405877642.jpg differ