TF Girls——总结(20)

GitHub:https://github.com/CreatCodeBuild/TensorFlow-and-DeepLearning-Tutorial/blob/master/Season1/20/load.py

 

### load.py



# encoding:utf-8

# Python2 兼容

from __future__ import print_function, division

from scipy.io import loadmat as load

import matplotlib.pyplot as plt

import numpy as np



def reformat(samples, labels):

	# 改变原始数据的形状

	#  0       1       2      3          3       0       1      2

	# (图片高,图片宽,通道数,图片数) -> (图片数,图片高,图片宽,通道数)

	new = np.transpose(samples, (3, 0, 1, 2)).astype(np.float32)



	# labels 变成 one-hot encoding, [2] -> [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]

	# digit 0 , represented as 10

	# labels 变成 one-hot encoding, [10] -> [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]

	labels = np.array([x[0] for x in labels])	# slow code, whatever

	one_hot_labels = []

	for num in labels:

		one_hot = [0.0] * 10

		if num == 10:

			one_hot[0] = 1.0

		else:

			one_hot[num] = 1.0

		one_hot_labels.append(one_hot)

	labels = np.array(one_hot_labels).astype(np.float32)

	return new, labels



def normalize(samples):

	'''

	并且灰度化: 从三色通道 -> 单色通道     省内存 + 加快训练速度

	(R + G + B) / 3

	将图片从 0 ~ 255 线性映射到 -1.0 ~ +1.0

	@samples: numpy array

	'''

	a = np.add.reduce(samples, keepdims=True, axis=3)  # shape (图片数,图片高,图片宽,通道数)

	a = a/3.0

	return a/128.0 - 1.0





def distribution(labels, name):

	# 查看一下每个label的分布,再画个统计图

	# keys:

	# 0

	# 1

	# 2

	# ...

	# 9

	count = {}

	for label in labels:

		key = 0 if label[0] == 10 else label[0]

		if key in count:

			count[key] += 1

		else:

			count[key] = 1

	x = []

	y = []

	for k, v in count.items():

		# print(k, v)

		x.append(k)

		y.append(v)



	y_pos = np.arange(len(x))

	plt.bar(y_pos, y, align='center', alpha=0.5)

	plt.xticks(y_pos, x)

	plt.ylabel('Count')

	plt.title(name + ' Label Distribution')

	plt.show()



def inspect(dataset, labels, i):

	# 显示图片看看

	if dataset.shape[3] == 1:

		shape = dataset.shape

		dataset = dataset.reshape(shape[0], shape[1], shape[2])

	print(labels[i])

	plt.imshow(dataset[i])

	plt.show()





train = load('../data/train_32x32.mat')

test = load('../data/test_32x32.mat')

# extra = load('../data/extra_32x32.mat')



# print('Train Samples Shape:', train['X'].shape)

# print('Train  Labels Shape:', train['y'].shape)



# print('Train Samples Shape:', test['X'].shape)

# print('Train  Labels Shape:', test['y'].shape)



# print('Train Samples Shape:', extra['X'].shape)

# print('Train  Labels Shape:', extra['y'].shape)



train_samples = train['X']

train_labels = train['y']

test_samples = test['X']

test_labels = test['y']

# extra_samples = extra['X']

# extra_labels = extra['y']



n_train_samples, _train_labels = reformat(train_samples, train_labels)

n_test_samples, _test_labels = reformat(test_samples, test_labels)



_train_samples = normalize(n_train_samples)

_test_samples = normalize(n_test_samples)



num_labels = 10

image_size = 32

num_channels = 1



if __name__ == '__main__':

	# 探索数据

	pass

	inspect(_train_samples, _train_labels, 1234)

	# _train_samples = normalize(_train_samples)

	# inspect(_train_samples, _train_labels, 1234)

	# distribution(train_labels, 'Train Labels')

	# distribution(test_labels, 'Test Labels')

 

 

# 新的 refined api 不支持 Python2

import tensorflow as tf

from sklearn.metrics import confusion_matrix

import numpy as np





class Network():

	def __init__(self, train_batch_size, test_batch_size, pooling_scale,

				       dropout_rate, base_learning_rate, decay_rate,

					   optimizeMethod='adam', save_path='model/default.ckpt'):

		'''

		@num_hidden: 隐藏层的节点数量

		@batch_size:因为我们要节省内存,所以分批处理数据。每一批的数据量。

		'''

		self.optimizeMethod = optimizeMethod

		self.dropout_rate=dropout_rate

		self.base_learning_rate=base_learning_rate

		self.decay_rate=decay_rate



		self.train_batch_size = train_batch_size

		self.test_batch_size = test_batch_size



		# Hyper Parameters

		self.conv_config = []		# list of dict

		self.fc_config = []			# list of dict

		self.conv_weights = []

		self.conv_biases = []

		self.fc_weights = []

		self.fc_biases = []

		self.pooling_scale = pooling_scale

		self.pooling_stride = pooling_scale



		# Graph Related

		self.tf_train_samples = None

		self.tf_train_labels = None

		self.tf_test_samples = None

		self.tf_test_labels = None



		# 统计

		self.writer = None

		self.merged = None

		self.train_summaries = []

		self.test_summaries = []



		# save 保存训练的模型

		self.saver = None

		self.save_path = save_path



	def add_conv(self, *, patch_size, in_depth, out_depth, activation='relu', pooling=False, name):

		'''

		This function does not define operations in the graph, but only store config in self.conv_layer_config

		'''

		self.conv_config.append({

			'patch_size': patch_size,

			'in_depth': in_depth,

			'out_depth': out_depth,

			'activation': activation,

			'pooling': pooling,

			'name': name

		})

		with tf.name_scope(name):

			weights = tf.Variable(

				tf.truncated_normal([patch_size, patch_size, in_depth, out_depth], stddev=0.1), name=name+'_weights')

			biases = tf.Variable(tf.constant(0.1, shape=[out_depth]), name=name+'_biases')

			self.conv_weights.append(weights)

			self.conv_biases.append(biases)



	def add_fc(self, *, in_num_nodes, out_num_nodes, activation='relu', name):

		'''

		add fc layer config to slef.fc_layer_config

		'''

		self.fc_config.append({

			'in_num_nodes': in_num_nodes,

			'out_num_nodes': out_num_nodes,

			'activation': activation,

			'name': name

		})

		with tf.name_scope(name):

			weights = tf.Variable(tf.truncated_normal([in_num_nodes, out_num_nodes], stddev=0.1))

			biases = tf.Variable(tf.constant(0.1, shape=[out_num_nodes]))

			self.fc_weights.append(weights)

			self.fc_biases.append(biases)

			self.train_summaries.append(tf.histogram_summary(str(len(self.fc_weights))+'_weights', weights))

			self.train_summaries.append(tf.histogram_summary(str(len(self.fc_biases))+'_biases', biases))



	def apply_regularization(self, _lambda):

		# L2 regularization for the fully connected parameters

		regularization = 0.0

		for weights, biases in zip(self.fc_weights, self.fc_biases):

			regularization += tf.nn.l2_loss(weights) + tf.nn.l2_loss(biases)

		# 1e5

		return _lambda * regularization



	# should make the definition as an exposed API, instead of implemented in the function

	def define_inputs(self, *, train_samples_shape, train_labels_shape, test_samples_shape):

		# 这里只是定义图谱中的各种变量

		with tf.name_scope('inputs'):

			self.tf_train_samples = tf.placeholder(tf.float32, shape=train_samples_shape, name='tf_train_samples')

			self.tf_train_labels = tf.placeholder(tf.float32, shape=train_labels_shape, name='tf_train_labels')

			self.tf_test_samples = tf.placeholder(tf.float32, shape=test_samples_shape, name='tf_test_samples')



	def define_model(self):

		'''

		定义我的的计算图谱

		'''

		def model(data_flow, train=True):

			'''

			@data: original inputs

			@return: logits

			'''

			# Define Convolutional Layers

			for i, (weights, biases, config) in enumerate(zip(self.conv_weights, self.conv_biases, self.conv_config)):

				with tf.name_scope(config['name'] + '_model'):

					with tf.name_scope('convolution'):

						# default 1,1,1,1 stride and SAME padding

						data_flow = tf.nn.conv2d(data_flow, filter=weights, strides=[1, 1, 1, 1], padding='SAME')

						data_flow = data_flow + biases

						if not train:

							self.visualize_filter_map(data_flow, how_many=config['out_depth'], display_size=32//(i//2+1), name=config['name']+'_conv')

					if config['activation'] == 'relu':

						data_flow = tf.nn.relu(data_flow)

						if not train:

							self.visualize_filter_map(data_flow, how_many=config['out_depth'], display_size=32//(i//2+1), name=config['name']+'_relu')

					else:

						raise Exception('Activation Func can only be Relu right now. You passed', config['activation'])

					if config['pooling']:

						data_flow = tf.nn.max_pool(

							data_flow,

							ksize=[1, self.pooling_scale, self.pooling_scale, 1],

							strides=[1, self.pooling_stride, self.pooling_stride, 1],

							padding='SAME')

						if not train:

							self.visualize_filter_map(data_flow, how_many=config['out_depth'], display_size=32//(i//2+1)//2, name=config['name']+'_pooling')



			# Define Fully Connected Layers

			for i, (weights, biases, config) in enumerate(zip(self.fc_weights, self.fc_biases, self.fc_config)):

				if i == 0:

					shape = data_flow.get_shape().as_list()

					data_flow = tf.reshape(data_flow, [shape[0], shape[1] * shape[2] * shape[3]])

				with tf.name_scope(config['name'] + 'model'):



					### Dropout

					if train and i == len(self.fc_weights) - 1:

						data_flow =  tf.nn.dropout(data_flow, self.dropout_rate, seed=4926)

					###



					data_flow = tf.matmul(data_flow, weights) + biases

					if config['activation'] == 'relu':

						data_flow = tf.nn.relu(data_flow)

					elif config['activation'] is None:

						pass

					else:

						raise Exception('Activation Func can only be Relu or None right now. You passed', config['activation'])

			return data_flow



		# Training computation.

		logits = model(self.tf_train_samples)

		with tf.name_scope('loss'):

			self.loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits, self.tf_train_labels))

			self.loss += self.apply_regularization(_lambda=5e-4)

			self.train_summaries.append(tf.scalar_summary('Loss', self.loss))



		# learning rate decay

		global_step = tf.Variable(0)

		learning_rate = tf.train.exponential_decay(

			learning_rate=self.base_learning_rate,

			global_step=global_step*self.train_batch_size,

			decay_steps=100,

			decay_rate=self.decay_rate,

			staircase=True

		)



		# Optimizer.

		with tf.name_scope('optimizer'):

			if(self.optimizeMethod=='gradient'):

				self.optimizer = tf.train \

					.GradientDescentOptimizer(learning_rate) \

					.minimize(self.loss)

			elif(self.optimizeMethod=='momentum'):

				self.optimizer = tf.train \

					.MomentumOptimizer(learning_rate, 0.5) \

					.minimize(self.loss)

			elif(self.optimizeMethod=='adam'):

				self.optimizer = tf.train \

					.AdamOptimizer(learning_rate) \

					.minimize(self.loss)



		# Predictions for the training, validation, and test data.

		with tf.name_scope('train'):

			self.train_prediction = tf.nn.softmax(logits, name='train_prediction')

			tf.add_to_collection("prediction", self.train_prediction)

		with tf.name_scope('test'):

			self.test_prediction = tf.nn.softmax(model(self.tf_test_samples, train=False), name='test_prediction')

			tf.add_to_collection("prediction", self.test_prediction)



			single_shape = (1, 32, 32, 1)

			single_input = tf.placeholder(tf.float32, shape=single_shape, name='single_input')

			self.single_prediction = tf.nn.softmax(model(single_input, train=False), name='single_prediction')

			tf.add_to_collection("prediction", self.single_prediction)



		self.merged_train_summary = tf.merge_summary(self.train_summaries)

		self.merged_test_summary = tf.merge_summary(self.test_summaries)



		# 放在定义Graph之后,保存这张计算图

		self.saver = tf.train.Saver(tf.all_variables())



	def run(self, train_samples, train_labels, test_samples, test_labels, *, train_data_iterator, iteration_steps, test_data_iterator):

		'''

		用到Session

		:data_iterator: a function that yields chuck of data

		'''

		self.writer = tf.train.SummaryWriter('./board', tf.get_default_graph())



		with tf.Session(graph=tf.get_default_graph()) as session:

			tf.initialize_all_variables().run()



			### 训练

			print('Start Training')

			# batch 1000

			for i, samples, labels in train_data_iterator(train_samples, train_labels, iteration_steps=iteration_steps, chunkSize=self.train_batch_size):

				_, l, predictions, summary = session.run(

					[self.optimizer, self.loss, self.train_prediction, self.merged_train_summary],

					feed_dict={self.tf_train_samples: samples, self.tf_train_labels: labels}

				)

				self.writer.add_summary(summary, i)

				# labels is True Labels

				accuracy, _ = self.accuracy(predictions, labels)

				if i % 50 == 0:

					print('Minibatch loss at step %d: %f' % (i, l))

					print('Minibatch accuracy: %.1f%%' % accuracy)

			###



			### 测试

			accuracies = []

			confusionMatrices = []

			for i, samples, labels in test_data_iterator(test_samples, test_labels, chunkSize=self.test_batch_size):

				result, summary = session.run(

					[self.test_prediction, self.merged_test_summary],

					feed_dict={self.tf_test_samples: samples}

				)

				self.writer.add_summary(summary, i)

				accuracy, cm = self.accuracy(result, labels, need_confusion_matrix=True)

				accuracies.append(accuracy)

				confusionMatrices.append(cm)

				print('Test Accuracy: %.1f%%' % accuracy)

			print(' Average  Accuracy:', np.average(accuracies))

			print('Standard Deviation:', np.std(accuracies))

			self.print_confusion_matrix(np.add.reduce(confusionMatrices))

			###



	def train(self, train_samples, train_labels, *, data_iterator, iteration_steps):

		self.writer = tf.train.SummaryWriter('./board', tf.get_default_graph())

		with tf.Session(graph=tf.get_default_graph()) as session:

			tf.initialize_all_variables().run()



			### 训练

			print('Start Training')

			# batch 1000

			for i, samples, labels in data_iterator(train_samples, train_labels, iteration_steps=iteration_steps, chunkSize=self.train_batch_size):

				_, l, predictions, summary = session.run(

					[self.optimizer, self.loss, self.train_prediction, self.merged_train_summary],

					feed_dict={self.tf_train_samples: samples, self.tf_train_labels: labels}

				)

				self.writer.add_summary(summary, i)

				# labels is True Labels

				accuracy, _ = self.accuracy(predictions, labels)

				if i % 50 == 0:

					print('Minibatch loss at step %d: %f' % (i, l))

					print('Minibatch accuracy: %.1f%%' % accuracy)

			###



			# 检查要存放的路径值否存在。这里假定只有一层路径。

			import os

			if os.path.isdir(self.save_path.split('/')[0]):

				save_path = self.saver.save(session, self.save_path)

				print("Model saved in file: %s" % save_path)

			else:

				os.makedirs(self.save_path.split('/')[0])

				save_path = self.saver.save(session, self.save_path)

				print("Model saved in file: %s" % save_path)



	def test(self, test_samples, test_labels, *, data_iterator):

		if self.saver is None:

			self.define_model()

		if self.writer is None:

			self.writer = tf.train.SummaryWriter('./board', tf.get_default_graph())

		

		print('Before session')

		with tf.Session(graph=tf.get_default_graph()) as session:

			self.saver.restore(session, self.save_path)

			### 测试

			accuracies = []

			confusionMatrices = []

			for i, samples, labels in data_iterator(test_samples, test_labels, chunkSize=self.test_batch_size):

				result= session.run(

					self.test_prediction,

					feed_dict={self.tf_test_samples: samples}

				)

				#self.writer.add_summary(summary, i)

				accuracy, cm = self.accuracy(result, labels, need_confusion_matrix=True)

				accuracies.append(accuracy)

				confusionMatrices.append(cm)

				print('Test Accuracy: %.1f%%' % accuracy)

			print(' Average  Accuracy:', np.average(accuracies))

			print('Standard Deviation:', np.std(accuracies))

			self.print_confusion_matrix(np.add.reduce(confusionMatrices))

			###





	def accuracy(self, predictions, labels, need_confusion_matrix=False):

		'''

		计算预测的正确率与召回率

		@return: accuracy and confusionMatrix as a tuple

		'''

		_predictions = np.argmax(predictions, 1)

		_labels = np.argmax(labels, 1)

		cm = confusion_matrix(_labels, _predictions) if need_confusion_matrix else None

		# == is overloaded for numpy array

		accuracy = (100.0 * np.sum(_predictions == _labels) / predictions.shape[0])

		return accuracy, cm



	def visualize_filter_map(self, tensor, *, how_many, display_size, name):

		#print(tensor.get_shape)

		filter_map = tensor[-1]

		#print(filter_map.get_shape())

		filter_map = tf.transpose(filter_map, perm=[2, 0, 1])

		#print(filter_map.get_shape())

		filter_map = tf.reshape(filter_map, (how_many, display_size, display_size, 1))

		#print(how_many)

		self.test_summaries.append(tf.image_summary(name, tensor=filter_map, max_images=how_many))



	def print_confusion_matrix(self, confusionMatrix):

		print('Confusion    Matrix:')

		for i, line in enumerate(confusionMatrix):

			print(line, line[i] / np.sum(line))

		a = 0

		for i, column in enumerate(np.transpose(confusionMatrix, (1, 0))):

			a += (column[i] / np.sum(column)) * (np.sum(column) / 26000)

			print(column[i] / np.sum(column), )

		print('\n', np.sum(confusionMatrix), a)

 

### dp.py



# 新的 refined api 不支持 Python2

import tensorflow as tf

from sklearn.metrics import confusion_matrix

import numpy as np





class Network():

	def __init__(self, train_batch_size, test_batch_size, pooling_scale,

				       dropout_rate, base_learning_rate, decay_rate,

					   optimizeMethod='adam', save_path='model/default.ckpt'):

		'''

		@num_hidden: 隐藏层的节点数量

		@batch_size:因为我们要节省内存,所以分批处理数据。每一批的数据量。

		'''

		self.optimizeMethod = optimizeMethod

		self.dropout_rate=dropout_rate

		self.base_learning_rate=base_learning_rate

		self.decay_rate=decay_rate



		self.train_batch_size = train_batch_size

		self.test_batch_size = test_batch_size



		# Hyper Parameters

		self.conv_config = []		# list of dict

		self.fc_config = []			# list of dict

		self.conv_weights = []

		self.conv_biases = []

		self.fc_weights = []

		self.fc_biases = []

		self.pooling_scale = pooling_scale

		self.pooling_stride = pooling_scale



		# Graph Related

		self.tf_train_samples = None

		self.tf_train_labels = None

		self.tf_test_samples = None

		self.tf_test_labels = None



		# 统计

		self.writer = None

		self.merged = None

		self.train_summaries = []

		self.test_summaries = []



		# save 保存训练的模型

		self.saver = None

		self.save_path = save_path



	def add_conv(self, *, patch_size, in_depth, out_depth, activation='relu', pooling=False, name):

		'''

		This function does not define operations in the graph, but only store config in self.conv_layer_config

		'''

		self.conv_config.append({

			'patch_size': patch_size,

			'in_depth': in_depth,

			'out_depth': out_depth,

			'activation': activation,

			'pooling': pooling,

			'name': name

		})

		with tf.name_scope(name):

			weights = tf.Variable(

				tf.truncated_normal([patch_size, patch_size, in_depth, out_depth], stddev=0.1), name=name+'_weights')

			biases = tf.Variable(tf.constant(0.1, shape=[out_depth]), name=name+'_biases')

			self.conv_weights.append(weights)

			self.conv_biases.append(biases)



	def add_fc(self, *, in_num_nodes, out_num_nodes, activation='relu', name):

		'''

		add fc layer config to slef.fc_layer_config

		'''

		self.fc_config.append({

			'in_num_nodes': in_num_nodes,

			'out_num_nodes': out_num_nodes,

			'activation': activation,

			'name': name

		})

		with tf.name_scope(name):

			weights = tf.Variable(tf.truncated_normal([in_num_nodes, out_num_nodes], stddev=0.1))

			biases = tf.Variable(tf.constant(0.1, shape=[out_num_nodes]))

			self.fc_weights.append(weights)

			self.fc_biases.append(biases)

			self.train_summaries.append(tf.histogram_summary(str(len(self.fc_weights))+'_weights', weights))

			self.train_summaries.append(tf.histogram_summary(str(len(self.fc_biases))+'_biases', biases))



	def apply_regularization(self, _lambda):

		# L2 regularization for the fully connected parameters

		regularization = 0.0

		for weights, biases in zip(self.fc_weights, self.fc_biases):

			regularization += tf.nn.l2_loss(weights) + tf.nn.l2_loss(biases)

		# 1e5

		return _lambda * regularization



	# should make the definition as an exposed API, instead of implemented in the function

	def define_inputs(self, *, train_samples_shape, train_labels_shape, test_samples_shape):

		# 这里只是定义图谱中的各种变量

		with tf.name_scope('inputs'):

			self.tf_train_samples = tf.placeholder(tf.float32, shape=train_samples_shape, name='tf_train_samples')

			self.tf_train_labels = tf.placeholder(tf.float32, shape=train_labels_shape, name='tf_train_labels')

			self.tf_test_samples = tf.placeholder(tf.float32, shape=test_samples_shape, name='tf_test_samples')



	def define_model(self):

		'''

		定义我的的计算图谱

		'''

		def model(data_flow, train=True):

			'''

			@data: original inputs

			@return: logits

			'''

			# Define Convolutional Layers

			for i, (weights, biases, config) in enumerate(zip(self.conv_weights, self.conv_biases, self.conv_config)):

				with tf.name_scope(config['name'] + '_model'):

					with tf.name_scope('convolution'):

						# default 1,1,1,1 stride and SAME padding

						data_flow = tf.nn.conv2d(data_flow, filter=weights, strides=[1, 1, 1, 1], padding='SAME')

						data_flow = data_flow + biases

						if not train:

							self.visualize_filter_map(data_flow, how_many=config['out_depth'], display_size=32//(i//2+1), name=config['name']+'_conv')

					if config['activation'] == 'relu':

						data_flow = tf.nn.relu(data_flow)

						if not train:

							self.visualize_filter_map(data_flow, how_many=config['out_depth'], display_size=32//(i//2+1), name=config['name']+'_relu')

					else:

						raise Exception('Activation Func can only be Relu right now. You passed', config['activation'])

					if config['pooling']:

						data_flow = tf.nn.max_pool(

							data_flow,

							ksize=[1, self.pooling_scale, self.pooling_scale, 1],

							strides=[1, self.pooling_stride, self.pooling_stride, 1],

							padding='SAME')

						if not train:

							self.visualize_filter_map(data_flow, how_many=config['out_depth'], display_size=32//(i//2+1)//2, name=config['name']+'_pooling')



			# Define Fully Connected Layers

			for i, (weights, biases, config) in enumerate(zip(self.fc_weights, self.fc_biases, self.fc_config)):

				if i == 0:

					shape = data_flow.get_shape().as_list()

					data_flow = tf.reshape(data_flow, [shape[0], shape[1] * shape[2] * shape[3]])

				with tf.name_scope(config['name'] + 'model'):



					### Dropout

					if train and i == len(self.fc_weights) - 1:

						data_flow =  tf.nn.dropout(data_flow, self.dropout_rate, seed=4926)

					###



					data_flow = tf.matmul(data_flow, weights) + biases

					if config['activation'] == 'relu':

						data_flow = tf.nn.relu(data_flow)

					elif config['activation'] is None:

						pass

					else:

						raise Exception('Activation Func can only be Relu or None right now. You passed', config['activation'])

			return data_flow



		# Training computation.

		logits = model(self.tf_train_samples)

		with tf.name_scope('loss'):

			self.loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits, self.tf_train_labels))

			self.loss += self.apply_regularization(_lambda=5e-4)

			self.train_summaries.append(tf.scalar_summary('Loss', self.loss))



		# learning rate decay

		global_step = tf.Variable(0)

		learning_rate = tf.train.exponential_decay(

			learning_rate=self.base_learning_rate,

			global_step=global_step*self.train_batch_size,

			decay_steps=100,

			decay_rate=self.decay_rate,

			staircase=True

		)



		# Optimizer.

		with tf.name_scope('optimizer'):

			if(self.optimizeMethod=='gradient'):

				self.optimizer = tf.train \

					.GradientDescentOptimizer(learning_rate) \

					.minimize(self.loss)

			elif(self.optimizeMethod=='momentum'):

				self.optimizer = tf.train \

					.MomentumOptimizer(learning_rate, 0.5) \

					.minimize(self.loss)

			elif(self.optimizeMethod=='adam'):

				self.optimizer = tf.train \

					.AdamOptimizer(learning_rate) \

					.minimize(self.loss)



		# Predictions for the training, validation, and test data.

		with tf.name_scope('train'):

			self.train_prediction = tf.nn.softmax(logits, name='train_prediction')

			tf.add_to_collection("prediction", self.train_prediction)

		with tf.name_scope('test'):

			self.test_prediction = tf.nn.softmax(model(self.tf_test_samples, train=False), name='test_prediction')

			tf.add_to_collection("prediction", self.test_prediction)



			single_shape = (1, 32, 32, 1)

			single_input = tf.placeholder(tf.float32, shape=single_shape, name='single_input')

			self.single_prediction = tf.nn.softmax(model(single_input, train=False), name='single_prediction')

			tf.add_to_collection("prediction", self.single_prediction)



		self.merged_train_summary = tf.merge_summary(self.train_summaries)

		self.merged_test_summary = tf.merge_summary(self.test_summaries)



		# 放在定义Graph之后,保存这张计算图

		self.saver = tf.train.Saver(tf.all_variables())



	def run(self, train_samples, train_labels, test_samples, test_labels, *, train_data_iterator, iteration_steps, test_data_iterator):

		'''

		用到Session

		:data_iterator: a function that yields chuck of data

		'''

		self.writer = tf.train.SummaryWriter('./board', tf.get_default_graph())



		with tf.Session(graph=tf.get_default_graph()) as session:

			tf.initialize_all_variables().run()



			### 训练

			print('Start Training')

			# batch 1000

			for i, samples, labels in train_data_iterator(train_samples, train_labels, iteration_steps=iteration_steps, chunkSize=self.train_batch_size):

				_, l, predictions, summary = session.run(

					[self.optimizer, self.loss, self.train_prediction, self.merged_train_summary],

					feed_dict={self.tf_train_samples: samples, self.tf_train_labels: labels}

				)

				self.writer.add_summary(summary, i)

				# labels is True Labels

				accuracy, _ = self.accuracy(predictions, labels)

				if i % 50 == 0:

					print('Minibatch loss at step %d: %f' % (i, l))

					print('Minibatch accuracy: %.1f%%' % accuracy)

			###



			### 测试

			accuracies = []

			confusionMatrices = []

			for i, samples, labels in test_data_iterator(test_samples, test_labels, chunkSize=self.test_batch_size):

				result, summary = session.run(

					[self.test_prediction, self.merged_test_summary],

					feed_dict={self.tf_test_samples: samples}

				)

				self.writer.add_summary(summary, i)

				accuracy, cm = self.accuracy(result, labels, need_confusion_matrix=True)

				accuracies.append(accuracy)

				confusionMatrices.append(cm)

				print('Test Accuracy: %.1f%%' % accuracy)

			print(' Average  Accuracy:', np.average(accuracies))

			print('Standard Deviation:', np.std(accuracies))

			self.print_confusion_matrix(np.add.reduce(confusionMatrices))

			###



	def train(self, train_samples, train_labels, *, data_iterator, iteration_steps):

		self.writer = tf.train.SummaryWriter('./board', tf.get_default_graph())

		with tf.Session(graph=tf.get_default_graph()) as session:

			tf.initialize_all_variables().run()



			### 训练

			print('Start Training')

			# batch 1000

			for i, samples, labels in data_iterator(train_samples, train_labels, iteration_steps=iteration_steps, chunkSize=self.train_batch_size):

				_, l, predictions, summary = session.run(

					[self.optimizer, self.loss, self.train_prediction, self.merged_train_summary],

					feed_dict={self.tf_train_samples: samples, self.tf_train_labels: labels}

				)

				self.writer.add_summary(summary, i)

				# labels is True Labels

				accuracy, _ = self.accuracy(predictions, labels)

				if i % 50 == 0:

					print('Minibatch loss at step %d: %f' % (i, l))

					print('Minibatch accuracy: %.1f%%' % accuracy)

			###



			# 检查要存放的路径值否存在。这里假定只有一层路径。

			import os

			if os.path.isdir(self.save_path.split('/')[0]):

				save_path = self.saver.save(session, self.save_path)

				print("Model saved in file: %s" % save_path)

			else:

				os.makedirs(self.save_path.split('/')[0])

				save_path = self.saver.save(session, self.save_path)

				print("Model saved in file: %s" % save_path)



	def test(self, test_samples, test_labels, *, data_iterator):

		if self.saver is None:

			self.define_model()

		if self.writer is None:

			self.writer = tf.train.SummaryWriter('./board', tf.get_default_graph())

		

		print('Before session')

		with tf.Session(graph=tf.get_default_graph()) as session:

			self.saver.restore(session, self.save_path)

			### 测试

			accuracies = []

			confusionMatrices = []

			for i, samples, labels in data_iterator(test_samples, test_labels, chunkSize=self.test_batch_size):

				result= session.run(

					self.test_prediction,

					feed_dict={self.tf_test_samples: samples}

				)

				#self.writer.add_summary(summary, i)

				accuracy, cm = self.accuracy(result, labels, need_confusion_matrix=True)

				accuracies.append(accuracy)

				confusionMatrices.append(cm)

				print('Test Accuracy: %.1f%%' % accuracy)

			print(' Average  Accuracy:', np.average(accuracies))

			print('Standard Deviation:', np.std(accuracies))

			self.print_confusion_matrix(np.add.reduce(confusionMatrices))

			###





	def accuracy(self, predictions, labels, need_confusion_matrix=False):

		'''

		计算预测的正确率与召回率

		@return: accuracy and confusionMatrix as a tuple

		'''

		_predictions = np.argmax(predictions, 1)

		_labels = np.argmax(labels, 1)

		cm = confusion_matrix(_labels, _predictions) if need_confusion_matrix else None

		# == is overloaded for numpy array

		accuracy = (100.0 * np.sum(_predictions == _labels) / predictions.shape[0])

		return accuracy, cm



	def visualize_filter_map(self, tensor, *, how_many, display_size, name):

		#print(tensor.get_shape)

		filter_map = tensor[-1]

		#print(filter_map.get_shape())

		filter_map = tf.transpose(filter_map, perm=[2, 0, 1])

		#print(filter_map.get_shape())

		filter_map = tf.reshape(filter_map, (how_many, display_size, display_size, 1))

		#print(how_many)

		self.test_summaries.append(tf.image_summary(name, tensor=filter_map, max_images=how_many))



	def print_confusion_matrix(self, confusionMatrix):

		print('Confusion    Matrix:')

		for i, line in enumerate(confusionMatrix):

			print(line, line[i] / np.sum(line))

		a = 0

		for i, column in enumerate(np.transpose(confusionMatrix, (1, 0))):

			a += (column[i] / np.sum(column)) * (np.sum(column) / 26000)

			print(column[i] / np.sum(column), )

		print('\n', np.sum(confusionMatrix), a)
### main.py



if __name__ == '__main__':

	import load

	from dp import Network



	train_samples, train_labels = load._train_samples, load._train_labels

	test_samples, test_labels = load._test_samples, load._test_labels



	print('Training set', train_samples.shape, train_labels.shape)

	print('    Test set', test_samples.shape, test_labels.shape)



	image_size = load.image_size

	num_labels = load.num_labels

	num_channels = load.num_channels



	def train_data_iterator(samples, labels, iteration_steps, chunkSize):

		'''

		Iterator/Generator: get a batch of data

		这个函数是一个迭代器/生成器,用于每一次只得到 chunkSize 这么多的数据

		用于 for loop, just like range() function

		'''

		if len(samples) != len(labels):

			raise Exception('Length of samples and labels must equal')

		stepStart = 0  # initial step

		i = 0

		while i < iteration_steps:

			stepStart = (i * chunkSize) % (labels.shape[0] - chunkSize)

			yield i, samples[stepStart:stepStart + chunkSize], labels[stepStart:stepStart + chunkSize]

			i += 1



	def test_data_iterator(samples, labels, chunkSize):

		'''

		Iterator/Generator: get a batch of data

		这个函数是一个迭代器/生成器,用于每一次只得到 chunkSize 这么多的数据

		用于 for loop, just like range() function

		'''

		if len(samples) != len(labels):

			raise Exception('Length of samples and labels must equal')

		stepStart = 0  # initial step

		i = 0

		while stepStart < len(samples):

			stepEnd = stepStart + chunkSize

			if stepEnd < len(samples):

				yield i, samples[stepStart:stepEnd], labels[stepStart:stepEnd]

				i += 1

			stepStart = stepEnd





	net = Network(

		train_batch_size=64, test_batch_size=500, pooling_scale=2,

		dropout_rate = 0.9,

		base_learning_rate = 0.001, decay_rate=0.99)

	net.define_inputs(

			train_samples_shape=(64, image_size, image_size, num_channels),

			train_labels_shape=(64, num_labels),

			test_samples_shape=(500, image_size, image_size, num_channels),

		)

	#

	net.add_conv(patch_size=3, in_depth=num_channels, out_depth=32, activation='relu', pooling=False, name='conv1')

	net.add_conv(patch_size=3, in_depth=32, out_depth=32, activation='relu', pooling=True, name='conv2')

	net.add_conv(patch_size=3, in_depth=32, out_depth=32, activation='relu', pooling=False, name='conv3')

	net.add_conv(patch_size=3, in_depth=32, out_depth=32, activation='relu', pooling=True, name='conv4')



	# 4 = 两次 pooling, 每一次缩小为 1/2

	# 32 = conv4 out_depth

	net.add_fc(in_num_nodes=(image_size // 4) * (image_size // 4) * 32, out_num_nodes=128, activation='relu', name='fc1')

	net.add_fc(in_num_nodes=128, out_num_nodes=10, activation=None, name='fc2')



	net.define_model()

	#net.run(train_samples, train_labels, test_samples, test_labels, train_data_iterator=train_data_iterator, iteration_steps=3000, test_data_iterator=test_data_iterator)

	#net.train(train_samples, train_labels, data_iterator=train_data_iterator, iteration_steps=2000)

	net.test(test_samples, test_labels, data_iterator=test_data_iterator)



else:

	raise Exception('main.py: Should Not Be Imported!!! Must Run by "python main.py"')

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值