diff --git a/densenet.py b/densenet.py new file mode 100644 index 0000000..caf8eac --- /dev/null +++ b/densenet.py @@ -0,0 +1,153 @@ +import os +os.environ['TL_BACKEND'] = 'tensorflow' +import time +import multiprocessing +import tensorflow as tf +from tensorlayer.models import TrainOneStep +from tensorlayer.layers import Module +import tensorlayer as tl +from torchsummary import summary +from tensorlayer import logging +from tensorlayer.files import (assign_weights, maybe_download_and_extract) +from tensorlayer.layers import (BatchNorm, Conv2d, Dense, Elementwise, AdaptiveMeanPool2d, MaxPool2d , MeanPool2d,Concat,Dropout) +from tensorlayer.layers import Module, SequentialLayer + + +class _DenseLayer(Module): + def __init__(self, in_channels, growth_rate, bn_size): + super(_DenseLayer, self).__init__() + W_init = tl.initializers.truncated_normal(stddev=5e-2) + W_init2 = tl.initializers.truncated_normal(stddev=0.04) + b_init2 = tl.initializers.constant(value=0.1) + self.layer_list = [] + self.layer_list.append(Conv2d(bn_size * growth_rate,(1,1),in_channels=in_channels,W_init=W_init)) + self.layer_list.append(BatchNorm(num_features=bn_size * growth_rate,act='relu')) + self.layer_list.append(Conv2d(growth_rate, (3, 3), in_channels=bn_size * growth_rate,W_init=W_init)) + self.layer_list.append(BatchNorm(num_features=growth_rate, act='relu')) + self.dense_layer = SequentialLayer(self.layer_list) + self.concat = Concat(1) + + # 重载forward函数 + def forward(self, x): + new_features = self.dense_layer(x) + return self.concat([x, new_features]) + + +class _DenseBlock(Module): + def __init__(self, num_layers, in_channels, bn_size, growth_rate): + super(_DenseBlock, self).__init__() + W_init = tl.initializers.truncated_normal(stddev=5e-2) + W_init2 = tl.initializers.truncated_normal(stddev=0.04) + b_init2 = tl.initializers.constant(value=0.1) + self.layer_list = [] + for i in range(num_layers): + self.layer_list.append(_DenseLayer(in_channels + growth_rate * i,growth_rate, bn_size)) + self.dense_block = SequentialLayer(self.layer_list) + + # 重载forward函数 + def forward(self, x): + return self.dense_block(x) + + +class _Transition(Module): + def __init__(self, in_channels, out_channels): + super(_Transition, self).__init__() + W_init = tl.initializers.truncated_normal(stddev=5e-2) + W_init2 = tl.initializers.truncated_normal(stddev=0.04) + b_init2 = tl.initializers.constant(value=0.1) + self.layer_list = [] + self.layer_list.append(Conv2d(out_channels,(1,1),in_channels=in_channels,W_init=W_init)) + self.layer_list.append(BatchNorm(num_features=out_channels,act='relu')) + self.layer_list.append(MeanPool2d((2,2),strides=(2,2))) + self.transition_layer = SequentialLayer(self.layer_list) + + # 重载forward函数 + def forward(self, x): + return self.transition_layer(x) + +class DenseNet_BC(Module): + def __init__(self, growth_rate=12, block_config=(6, 12, 24, 16), + bn_size=4, theta=0.5, num_classes=10): + super(DenseNet_BC, self).__init__() + W_init = tl.initializers.truncated_normal(stddev=5e-2) + W_init2 = tl.initializers.truncated_normal(stddev=0.04) + b_init2 = tl.initializers.constant(value=0.1) + # 初始的卷积为filter:2倍的growth_rate + num_init_feature = 2 * growth_rate + self.layer_list = [] + # 表示cifar-10 + if num_classes == 10: + self.layer_list.append(Conv2d(num_init_feature,(3,3),strides=(1,1),in_channels=3,W_init=W_init)) + + else: + self.layer_list.append(Conv2d(num_init_feature,(7,7),strides=(2,2),padding="valid",in_channels=3,W_init=W_init)) + self.layer_list.append(BatchNorm(num_features=num_init_feature,act='relu')) + self.layer_list.append(MaxPool2d((3, 3), strides=(2, 2))) + + + num_feature = num_init_feature + for i, num_layers in enumerate(block_config): + self.layer_list.append( _DenseBlock(num_layers, num_feature,bn_size, growth_rate)) + num_feature = num_feature + growth_rate * num_layers + if i != len(block_config) - 1: + self.layer_list.append(_Transition(num_feature,int(num_feature * theta))) + num_feature = int(num_feature * theta) + + self.layer_list.append(BatchNorm(num_features=num_feature,act='relu')) + self.layer_list.append(AdaptiveMeanPool2d((1,1))) + + self.features = SequentialLayer(self.layer_list) + self.classifier = Dense(num_feature, num_classes,W_init=W_init2,b_init=b_init2) + + + def forward(self, x): + features = self.features(x) + out = features.view(features.size(0), -1) + out = self.classifier(out) + return out + + +# DenseNet_BC for ImageNet +def DenseNet121(): + return DenseNet_BC(growth_rate=32, block_config=(6, 12, 24, 16), num_classes=1000) + + +def DenseNet169(): + return DenseNet_BC(growth_rate=32, block_config=(6, 12, 32, 32), num_classes=1000) + + +def DenseNet201(): + return DenseNet_BC(growth_rate=32, block_config=(6, 12, 48, 32), num_classes=1000) + + +def DenseNet161(): + return DenseNet_BC(growth_rate=48, block_config=(6, 12, 36, 24), num_classes=1000, ) + + +# DenseNet_BC for cifar +def densenet_BC_100(): + return DenseNet_BC(growth_rate=12, block_config=(16, 16, 16)) + +def builddensenet(name = "densenet-100"): + if name == "densenet-100": + return densenet_BC_100() + elif name == "densenet-121": + return DenseNet121() + else: + print("not found the net") + exit(0) + +def test(): + net = densenet_BC_100() + print(summary(net, input_size=(3, 32, 32))) + + #x = torch.randn(2, 3, 32, 32) + # y = net(x) + # print(y.size()) + + +if __name__ == '__main__': + test() + + + diff --git a/densenet_cifar.py b/densenet_cifar.py new file mode 100644 index 0000000..86f1dfb --- /dev/null +++ b/densenet_cifar.py @@ -0,0 +1,138 @@ +import os +os.environ['TL_BACKEND'] = 'tensorflow' +import time +import multiprocessing +import tensorflow as tf +from tensorlayer.models import TrainOneStep +from tensorlayer.layers import Module +import tensorlayer as tl +from .densenet import builddensenet + + +# enable debug logging +tl.logging.set_verbosity(tl.logging.DEBUG) + +# prepare cifar10 data +X_train, y_train, X_test, y_test = tl.files.load_cifar10_dataset(shape=(-1, 32, 32, 3), plotable=False) + + +# get the network +net = builddensenet("densenet-100") + +# training settings +batch_size = 128 +n_epoch = 500 +learning_rate = 0.0001 +print_freq = 5 +n_step_epoch = int(len(y_train) / batch_size) +n_step = n_epoch * n_step_epoch +shuffle_buffer_size = 128 + +train_weights = net.trainable_weights +optimizer = tl.optimizers.Adam(learning_rate) +metrics = tl.metric.Accuracy() + + +def generator_train(): + inputs = X_train + targets = y_train + if len(inputs) != len(targets): + raise AssertionError("The length of inputs and targets should be equal") + for _input, _target in zip(inputs, targets): + # yield _input.encode('utf-8'), _target.encode('utf-8') + yield _input, _target + + +def generator_test(): + inputs = X_test + targets = y_test + if len(inputs) != len(targets): + raise AssertionError("The length of inputs and targets should be equal") + for _input, _target in zip(inputs, targets): + # yield _input.encode('utf-8'), _target.encode('utf-8') + yield _input, _target + + +def _map_fn_train(img, target): + # 1. Randomly crop a [height, width] section of the image. + img = tf.image.random_crop(img, [24, 24, 3]) + # 2. Randomly flip the image horizontally. + img = tf.image.random_flip_left_right(img) + # 3. Randomly change brightness. + img = tf.image.random_brightness(img, max_delta=63) + # 4. Randomly change contrast. + img = tf.image.random_contrast(img, lower=0.2, upper=1.8) + # 5. Subtract off the mean and divide by the variance of the pixels. + img = tf.image.per_image_standardization(img) + target = tf.reshape(target, ()) + return img, target + + +def _map_fn_test(img, target): + # 1. Crop the central [height, width] of the image. + img = tf.image.resize_with_pad(img, 24, 24) + # 2. Subtract off the mean and divide by the variance of the pixels. + img = tf.image.per_image_standardization(img) + img = tf.reshape(img, (24, 24, 3)) + target = tf.reshape(target, ()) + return img, target + + +# dataset API and augmentation +train_ds = tf.data.Dataset.from_generator( + generator_train, output_types=(tf.float32, tf.int32) +) # , output_shapes=((24, 24, 3), (1))) +train_ds = train_ds.map(_map_fn_train, num_parallel_calls=multiprocessing.cpu_count()) +# train_ds = train_ds.repeat(n_epoch) +train_ds = train_ds.shuffle(shuffle_buffer_size) +train_ds = train_ds.prefetch(buffer_size=4096) +train_ds = train_ds.batch(batch_size) +# value = train_ds.make_one_shot_iterator().get_next() + +test_ds = tf.data.Dataset.from_generator( + generator_test, output_types=(tf.float32, tf.int32) +) # , output_shapes=((24, 24, 3), (1))) +# test_ds = test_ds.shuffle(shuffle_buffer_size) +test_ds = test_ds.map(_map_fn_test, num_parallel_calls=multiprocessing.cpu_count()) +# test_ds = test_ds.repeat(n_epoch) +test_ds = test_ds.prefetch(buffer_size=4096) +test_ds = test_ds.batch(batch_size) +# value_test = test_ds.make_one_shot_iterator().get_next() + + +class WithLoss(Module): + + def __init__(self, net, loss_fn): + super(WithLoss, self).__init__() + self._net = net + self._loss_fn = loss_fn + + def forward(self, data, label): + out = self._net(data) + loss = self._loss_fn(out, label) + return loss + + +net_with_loss = WithLoss(net, loss_fn=tl.cost.softmax_cross_entropy_with_logits) +net_with_train = TrainOneStep(net_with_loss, optimizer, train_weights) + +for epoch in range(n_epoch): + start_time = time.time() + net.set_train() + train_loss, train_acc, n_iter = 0, 0, 0 + for X_batch, y_batch in train_ds: + + X_batch = tl.ops.convert_to_tensor(X_batch.numpy(), dtype=tl.float32) + y_batch = tl.ops.convert_to_tensor(y_batch.numpy(), dtype=tl.int64) + + _loss_ce = net_with_train(X_batch, y_batch) + train_loss += _loss_ce + + n_iter += 1 + _logits = net(X_batch) + metrics.update(_logits, y_batch) + train_acc += metrics.result() + metrics.reset() + print("Epoch {} of {} took {}".format(epoch + 1, n_epoch, time.time() - start_time)) + print(" train loss: {}".format(train_loss / n_iter)) + print(" train acc: {}".format(train_acc / n_iter)) diff --git a/densenet_imagenet.py b/densenet_imagenet.py new file mode 100644 index 0000000..594f099 --- /dev/null +++ b/densenet_imagenet.py @@ -0,0 +1,145 @@ +import os +os.environ['TL_BACKEND'] = 'tensorflow' +import time +import multiprocessing +import tensorflow as tf +from tensorlayer.models import TrainOneStep +from tensorlayer.layers import Module +import tensorlayer as tl +from .densenet import builddensenet + +def load_imagenet_dataset(shape=(-1, 256, 256, 3), plotable=False): + """ + 此函数根据本地环境加载imagenet数据,返回 X_train, y_train, X_test, y_test(训练集图像、标签,测试集图像、标签) + """ + return None + + +# enable debug logging +tl.logging.set_verbosity(tl.logging.DEBUG) + +# prepare image_net data +X_train, y_train, X_test, y_test = load_imagenet_dataset(shape=(-1, 256, 256, 3), plotable=False) + + +# get the network +net = builddensenet("densenet-121") + +# training settings +batch_size = 128 +n_epoch = 500 +learning_rate = 0.0001 +print_freq = 5 +n_step_epoch = int(len(y_train) / batch_size) +n_step = n_epoch * n_step_epoch +shuffle_buffer_size = 128 + +train_weights = net.trainable_weights +optimizer = tl.optimizers.Adam(learning_rate) +metrics = tl.metric.Accuracy() + + + +def generator_train(): + inputs = X_train + targets = y_train + if len(inputs) != len(targets): + raise AssertionError("The length of inputs and targets should be equal") + for _input, _target in zip(inputs, targets): + # yield _input.encode('utf-8'), _target.encode('utf-8') + yield _input, _target + + +def generator_test(): + inputs = X_test + targets = y_test + if len(inputs) != len(targets): + raise AssertionError("The length of inputs and targets should be equal") + for _input, _target in zip(inputs, targets): + # yield _input.encode('utf-8'), _target.encode('utf-8') + yield _input, _target + + +def _map_fn_train(img, target): + # 1. Randomly crop a [height, width] section of the image. + img = tf.image.random_crop(img, [224, 224, 3]) + # 2. Randomly flip the image horizontally. + img = tf.image.random_flip_left_right(img) + # 3. Randomly change brightness. + img = tf.image.random_brightness(img, max_delta=63) + # 4. Randomly change contrast. + img = tf.image.random_contrast(img, lower=0.2, upper=1.8) + # 5. Subtract off the mean and divide by the variance of the pixels. + img = tf.image.per_image_standardization(img) + target = tf.reshape(target, ()) + return img, target + + +def _map_fn_test(img, target): + # 1. Crop the central [height, width] of the image. + img = tf.image.resize_with_pad(img, 224, 224) + # 2. Subtract off the mean and divide by the variance of the pixels. + img = tf.image.per_image_standardization(img) + img = tf.reshape(img, (224, 224, 3)) + target = tf.reshape(target, ()) + return img, target + + +# dataset API and augmentation +train_ds = tf.data.Dataset.from_generator( + generator_train, output_types=(tf.float32, tf.int32) +) # , output_shapes=((24, 24, 3), (1))) +train_ds = train_ds.map(_map_fn_train, num_parallel_calls=multiprocessing.cpu_count()) +# train_ds = train_ds.repeat(n_epoch) +train_ds = train_ds.shuffle(shuffle_buffer_size) +train_ds = train_ds.prefetch(buffer_size=4096) +train_ds = train_ds.batch(batch_size) +# value = train_ds.make_one_shot_iterator().get_next() + +test_ds = tf.data.Dataset.from_generator( + generator_test, output_types=(tf.float32, tf.int32) +) # , output_shapes=((24, 24, 3), (1))) +# test_ds = test_ds.shuffle(shuffle_buffer_size) +test_ds = test_ds.map(_map_fn_test, num_parallel_calls=multiprocessing.cpu_count()) +# test_ds = test_ds.repeat(n_epoch) +test_ds = test_ds.prefetch(buffer_size=4096) +test_ds = test_ds.batch(batch_size) +# value_test = test_ds.make_one_shot_iterator().get_next() + + +class WithLoss(Module): + + def __init__(self, net, loss_fn): + super(WithLoss, self).__init__() + self._net = net + self._loss_fn = loss_fn + + def forward(self, data, label): + out = self._net(data) + loss = self._loss_fn(out, label) + return loss + + +net_with_loss = WithLoss(net, loss_fn=tl.cost.softmax_cross_entropy_with_logits) +net_with_train = TrainOneStep(net_with_loss, optimizer, train_weights) + +for epoch in range(n_epoch): + start_time = time.time() + net.set_train() + train_loss, train_acc, n_iter = 0, 0, 0 + for X_batch, y_batch in train_ds: + + X_batch = tl.ops.convert_to_tensor(X_batch.numpy(), dtype=tl.float32) + y_batch = tl.ops.convert_to_tensor(y_batch.numpy(), dtype=tl.int64) + + _loss_ce = net_with_train(X_batch, y_batch) + train_loss += _loss_ce + + n_iter += 1 + _logits = net(X_batch) + metrics.update(_logits, y_batch) + train_acc += metrics.result() + metrics.reset() + print("Epoch {} of {} took {}".format(epoch + 1, n_epoch, time.time() - start_time)) + print(" train loss: {}".format(train_loss / n_iter)) + print(" train acc: {}".format(train_acc / n_iter))