1.a[len(a):len(a)]=[]
a=[]
a[len(a):len(a)]=[]可以用来扩展list,类似append,但是append,又类似于”整体加入“
a=[8,9]
print(a)
a[len(a):len(a)]=[1,2,3]
print(a,)
a.append([7,7])
print(a)
a.append('b')
print(a)
a.append(a)
print(a)
结果:
[8, 9]
[8, 9, 1, 2, 3]
[8, 9, 1, 2, 3, [7, 7]]
[8, 9, 1, 2, 3, [7, 7], 'b']
[8, 9, 1, 2, 3, [7, 7], 'b', [...]]
2.a[:-1]和a[::-1]
a = [0,1,2,3,4,5,6,7,8,9]
b = a[i:j] 表示复制a[i]到a[j-1],以生成新的list对象。b = a[1:3] 那么,b的内容是 [1,2]
当i缺省时,默认为0,当j缺省时,默认为len(alist), 当i,j都缺省时,a[:]就相当于完整复制一份a了
b = a[i:j:s],s表示步进,缺省为1.所以a[i:j:1]相当于a[i:j];当s<0时,i缺省时,默认为-1. j缺省时,默认为-len(a)-1
所以a[::-1]相当于 a[-1:-len(a)-1:-1],也就是从最后一个元素到第一个元素复制一遍。倒序。
3.tf.train.slice_input_producer()和tf.train.batch、tf.train.shuffle_batch
3.1tf.tain.slice_input_producer()是一个tensor生成器,作用是按照设定,每次从一个tensor列表中按顺序或者随机抽取出一个tensor放入文件名队列。还需要调用tf.train.start_queue_runners 函数来启动执行文件名队列填充的线程,之后计算单元才可以把数据读出来,否则文件名队列为空的,计算单元就会处于一直等待状态,导致系统阻塞。
tf.train.slice_input_producer(
tensor_list,
num_epochs=None,
shuffle=True,
seed=None,
capacity=32,
shared_name=None,
name=None
)
''' tensor_list:包含一系列tensor的列表,表中tensor的第一维度的值必须相等,即个数必须相等,有多少个图像,就应该有多少个对应的标签。
num_epochs: 可选,是一个整数值,代表迭代的次数,如果设置 num_epochs=None,生成器可以无限次遍历tensor列表,如果设置为 num_epochs=N,生成器只能遍历tensor列表N次。
shuffle: bool类型,设置是否打乱样本的顺序。一般情况下,如果shuffle=True,生成的样本顺序就被打乱了,在批处理的时候不需要再次打乱样本,使用 tf.train.batch函数就可以了;如果shuffle=False,就需要在批处理时候使用 tf.train.shuffle_batch函数打乱样本。
seed: 可选的整数,是生成随机数的种子,在第三个参数设置为shuffle=True的情况下才有用。
capacity:设置tensor列表的容量。
shared_name:可选参数,如果设置一个‘shared_name’,则在不同的上下文环境(Session)中可以通过这个名字共享生成的tensor。
name:可选,设置操作的名称。'''
输出为list:<class 'list'>: [<tf.Tensor 'input_producer/Gather:0' shape=() dtype=string>, <tf.Tensor 'input_producer/Gather_1:0' shape=() dtype=int32>]
[0]:输入队列;[1]:输出队列
tf.train.slice_input_producer([image,label],num_epochs=10)
上式随机产生一个图片和标签,num_epochs=10,则表示把所有的数据过10遍,使用完所有的图片数据为一个epoch,这是重复使用10次。上面的用法表示你的数据集和标签已经全部加载到内存中了,如果数据集非常庞大,我们通过这个函数也可以只加载图片的路径,放入图片的path,注意path必须是一个list或者tensorlist.
# 生成包含输入和目标图片地址名的list
input_files = [os.path.join(dirname, 'input', f) for f in flist]
output_files = [os.path.join(dirname, 'output', f) for f in flist]
# 内部自动转换为Constant String的Tensor,并排队进入队列
input_queue, output_queue = tf.train.slice_input_producer( [input_files, output_files], shuffle=self.shuffle, seed=0123, num_epochs=self.num_epochs)
# tf.train.slice_input_producer()每次取一对【输入-目标】对,交给ReadFile这个Op
input_file = tf.read_file(input_queue)
output_file = tf.read_file(output_queue)
# 生成RGB格式的图像tensor
im_input = tf.image.decode_jpeg(input_file, channels=3)
im_output = tf.image.decode_jpeg(output_file, channels=3)
#此部分参考:https://www.jianshu.com/p/8ba9cfc738c2
3.2tf.train.batch()
tf.train.batch(tensors, batch_size, num_threads=1, capacity=32,
enqueue_many=False, shapes=None, dynamic_pad=False,
allow_smaller_final_batch=False, shared_name=None, name=None)
tf.train.batch是按顺序读取数据,队列中的数据始终是一个有序的队列,作为训练一个batch的数据,等待tensor出队执行计算。
假设现在有个test.tfrecord文件,里面按从小到大顺序存放整数0~100队列的capacity=20,开始队列内容为0,1,..,19=>读取10条记录后,队列剩下10,11,..,19,然后又补充10条变成=>10,11,...,29,
队头一直按顺序补充,队尾一直按顺序出队,到了第100条记录后,又重头开始补充0,1,2...
输出的形状 [batch_size, x, y, z],深度学习中长为[batchsize,W,H,channel]
# Creates batches of 32 images and 32 labels.
image_batch, label_batch = tf.train.shuffle_batch(
[single_image, single_label],
batch_size=32,
num_threads=4,
capacity=50000,
min_after_dequeue=10000)
这段代码写的是从[single_image, single_label]利用4个线程读取32行
输出尺寸是image_batch:【batch_size,single_image】 label_batch:【batch_size,single_label】
如:single_image:Tensor("strided_slice:0", shape=(224, 224, 3), dtype=float32)
single_label:Tensor("one_hot:0", shape=(2,), dtype=uint8)
输出image_batch:Tensor("shuffle_batch:0", shape=(64, 224, 224, 3), dtype=float32)
label_batch:Tensor("shuffle_batch:1", shape=(64, 2), dtype=uint8)
3.3tf.train.shuffle_batch()
tf.train.shuffle_batch(tensor_list, batch_size, capacity, min_after_dequeue, num_threads=1, seed=None,enqueue_many=False, shapes=None, name=None)
capacity是队列的长度
min_after_dequeue是出队后,队列至少剩下min_after_dequeue个数据,因此队列中剩下的数据也是乱序的,队头也是一直在补充(我猜也是按顺序补充),
比如batch_size=5,capacity=10,min_after_dequeue=5,
初始是有序的0,1,..,9(10条记录),
然后打乱8,2,6,4,3,7,9,2,0,1(10条记录),
队尾取出5条,剩下7,9,2,0,1(5条记录),
然后又按顺序补充进来,变成7,9,2,0,1,10,11,12,13,14(10条记录),
再打乱13,10,2,7,0,12...1(10条记录),再出队...
以上部分可参考:原文:https://blog.csdn.net/ying86615791/article/details/73864381
综上:一个非常好使的,用于深度学习的代码段:
自动获取每个batch的数据, 使用队列可以把图片及对应的标签准确的取出来,同时还自动打乱顺序,非常好使用。
就像前面说的[0]:输入队列;[1]:输出队列,这里[0]:输入图像队列;[1]:标签队列,也就是输出结果队列
# 把图片数据转化为三维矩阵
class ImageDataGenerator(object):
def __init__(self, images, labels, batch_size, num_classes):
self.filenames = images
self.labels = labels
self.batch_size = batch_size
self.num_class = num_classes
self.image_batch, self.label_batch = self.image_decode()
def image_decode(self):
'''# 建立文件队列,把图片和对应的实际标签放入队列中
#注:在没有运行tf.train.start_queue_runners(sess=sess)之前,数据实际上是没有放入队列中的'''
file_queue = tf.train.slice_input_producer([self.filenames, self.labels])
# 把图片数据转化为三维BGR矩阵
image_content = tf.read_file(file_queue[0])#[0]:输入队列;[1]:输出队列
image_data = tf.image.decode_jpeg(image_content, channels=3)
image = tf.image.resize_images(image_data, [224, 224])
#预处理是从每个像素中减去在训练集上计算的平均RGB值
img_centered = tf.subtract(image, VGG_MEAN)
img_bgr = img_centered[:, :, ::-1]#[::-1]倒序 RGB→BGR
labels = tf.one_hot(file_queue[1],self.num_class, dtype=tf.uint8)
# 分batch从文件队列中读取数据
image_batch, label_batch = tf.train.shuffle_batch([img_bgr, labels],
batch_size=self.batch_size,
capacity=2000,
min_after_dequeue=1000)
return image_batch, label_batch
4.tf.one_hot()
tf.one_hot()函数是将input转化为one-hot类型数据输出,相当于将多个数值联合放在一起作为多个相同类型的向量,可用于表示各自的概率分布,通常用于分类任务中作为最后的FC层的输出,有时翻译成“独热”编码(one-hot encoding),独热编码一般是在有监督学习中对数据集进行标注时候使用的,指的是在分类问题中,将存在数据类别的那一类用X表示,不存在的用Y表示,这里的X常常是1, Y常常是0。
举个例子:
比如我们有一个5类分类问题,我们有数据(Xi,Yi),其中类别Yi有五种取值(因为是五类分类问题),所以如果Yj为第一类那么其独热编码为: [1,0,0,0,0],如果是第二类那么独热编码为:[0,1,0,0,0],也就是说只对存在有该类别的数的位置上进行标记为1,其他皆为0。这个编码方式经常用于多分类问题,特别是损失函数为交叉熵函数的时候。
one_hot(indices, depth, on_value=None, off_value=None, axis=None, dtype=None, name=None)
Returns a one-hot tensor.
indices表示输入的多个数值,通常是矩阵形式;depth表示输出的尺寸。由于one-hot类型数据长度为depth位,其中只用一位数字表示原输入数据,这里的on_value就是这个数字,默认值为1,one-hot数据的其他位用off_value表示,默认值为0。
tf.one_hot()函数规定输入的元素indices从0开始,最大的元素值不能超过(depth - 1),因此能够表示(depth + 1)个单位的输入。若输入的元素值超出范围,输出的编码均为 [0, 0 … 0, 0]。
indices = 0 对应的输出是[1, 0 … 0, 0], indices = 1 对应的输出是[0, 1 … 0, 0], 依次类推,最大可能值的输出是[0, 0 … 0, 1]。
例子:
labels = tf.one_hot(file_queue[1],self.num_class, dtype=tf.uint8)
#file_queue[1]:标签;self.num_class:分类类别
5.x=tf.reshape(botton,[-1,in_size])
x=tf.reshape(botton,[-1,25088])
这里如上层pool5的尺寸为[7,7,512],加上维度就是botton=[3,7,7,512],设置in_size=25088(7*7*512)
把x转为最后一个维度的向量,也就是(3,25088,)。
6.tf.nn.bias_add():
通俗解释:一个叫bias的向量加到一个叫value的矩阵上,是向量与矩阵的每一行进行相加,得到的结果和value矩阵大小相同。如 value:(3,25088),bias维度是[3,25088]
5.6常常合用用来求结果值:这里相当于[X‘W,X'W,.....]+[b1,b2,......]。
def fc_layer(self, bottom, in_size, out_size, name):
with tf.variable_scope(name):
weights, biases = self.get_fc_var(in_size, out_size, name)
x = tf.reshape(bottom, [-1, in_size])#flatten
fc = tf.nn.bias_add(tf.matmul(x, weights), biases)#tf.matmul 矩阵相乘 tf.nn.bias_add是向量与矩阵的每一行进行相加,得到的结果和value矩阵大小相同。
return fc