├── .gitignore ├── BP神经网络 ├── tensorflow_BP神经网络.py ├── tensorflow_BP神经网络1.py ├── tensorflow_bp神经网络2.py └── 遗传算法优化的BP神经网络.py ├── DNN ├── keras_dnn.py └── tensorflow_DNN.py ├── README.md ├── tensorflow.md ├── tensorflow_01.py ├── tensorflow_02_case.py ├── tensorflow_03_session.py ├── tensorflow_04_Variable.py ├── tensorflow_05_placeholder.py ├── tensorflow_10_dropout.py ├── tensorflow_11_CNN_卷积神经网络.py ├── tensorflow_12_save_神经网络.py ├── tesorflow_06_add_layer.py ├── tesorflow_07_构建神经网络.py ├── tesorflow_08_可视化好棒手_tensorboard1.py ├── tesorflow_09_可视化好棒手_tensorboard2.py ├── 手写数字识别 ├── input_data.py ├── my_mnist.py └── test_mnist.py ├── 猫狗识别 ├── evaluateCatOrDog.py ├── input_data.py ├── model.py └── training.py └── 验证码识别 ├── CodeDemo.py ├── getImg.py ├── input_data.py ├── model.py └── 验证码生成器.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.txt 2 | *.pyc 3 | *.jpg 4 | **/my_net/ 5 | *.gz 6 | **/saveNet/ 7 | -------------------------------------------------------------------------------- /BP神经网络/tensorflow_BP神经网络.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 用 drop out 解决 Overfitting 问题 3 | import tensorflow as tf 4 | #导入TensorFlow工具包并简称为tf 5 | 6 | from numpy.random import RandomState 7 | #导入numpy工具包,生成模拟数据集 8 | 9 | batch_size = 8 10 | #定义训练数据batch的大小 11 | 12 | w1 = tf.Variable(tf.random_normal([2,3],stddev=1,seed=1)) 13 | w2 = tf.Variable(tf.random_normal([3,1],stddev=1,seed=1)) 14 | #分别定义一二层和二三层之间的网络参数,标准差为1,随机产生的数保持一致 15 | 16 | x = tf.placeholder(tf.float32,shape=(None,2),name='x-input') 17 | y_ = tf.placeholder(tf.float32,shape=(None,1),name='y-input') 18 | #输入为两个维度,即两个特征,输出为一个标签,声明数据类型float32,None即一个batch大小 19 | #y_是真实的标签 20 | 21 | a = tf.matmul(x,w1) 22 | y = tf.matmul(a,w2) 23 | #定义神经网络前向传播过程 24 | 25 | cross_entropy = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y,1e-10,1.0))) 26 | train_step = tf.train.AdamOptimizer(0.001).minimize(cross_entropy) 27 | #定义损失函数和反向传播算法 28 | 29 | rdm = RandomState(1) 30 | dataset_size = 128 31 | #产生128组数据 32 | X = rdm.rand(dataset_size,2) 33 | Y = [[int(x1+x2 < 1)] for (x1,x2) in X] 34 | #将所有x1+x2<1的样本视为正样本,表示为1;其余为0 35 | 36 | #创建会话来运行TensorFlow程序 37 | with tf.Session() as sess: 38 | init_op = tf.global_variables_initializer() 39 | #初始化变量 40 | sess.run(init_op) 41 | 42 | print(sess.run(w1)) 43 | print(sess.run(w2)) 44 | #打印出训练网络之前网络参数的值 45 | 46 | STEPS = 5000 47 | #设置训练的轮数 48 | for i in range(STEPS): 49 | start = (i * batch_size) % dataset_size 50 | end = min(start+batch_size,dataset_size) 51 | #每次选取batch_size个样本进行训练 52 | 53 | sess.run(train_step,feed_dict={x:X[start:end],y_:Y[start:end]}) 54 | #通过选取的样本训练神经网络并更新参数 55 | 56 | if i%1000 == 0: 57 | total_cross_entropy = sess.run(cross_entropy,feed_dict={x:X,y_:Y}) 58 | print("After %d training step(s),cross entropy on all data is %g" % (i,total_cross_entropy)) 59 | #每隔一段时间计算在所有数据上的交叉熵并输出,随着训练的进行,交叉熵逐渐变小 60 | 61 | print(sess.run(w1)) 62 | print(sess.run(w2)) 63 | #打印出训练之后神经网络参数的值 -------------------------------------------------------------------------------- /BP神经网络/tensorflow_BP神经网络1.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | import numpy as np 3 | 4 | def addLayer(inputData,inSize,outSize,activity_function = None): 5 | Weights = tf.Variable(tf.random_normal([inSize,outSize])) 6 | basis = tf.Variable(tf.zeros([1,outSize])+0.1) 7 | weights_plus_b = tf.matmul(inputData,Weights)+basis 8 | if activity_function is None: 9 | ans = weights_plus_b 10 | else: 11 | ans = activity_function(weights_plus_b) 12 | return ans 13 | 14 | 15 | x_data = np.linspace(-1,1,300)[:,np.newaxis] # 转为列向量 16 | noise = np.random.normal(0,0.05,x_data.shape) 17 | y_data = np.square(x_data)+0.5+noise 18 | 19 | 20 | xs = tf.placeholder(tf.float32,[None,1]) # 样本数未知,特征数为1,占位符最后要以字典形式在运行中填入 21 | ys = tf.placeholder(tf.float32,[None,1]) 22 | 23 | l1 = addLayer(xs,1,10,activity_function=tf.nn.relu) # relu是激励函数的一种 24 | l2 = addLayer(l1,10,1,activity_function=None) 25 | loss = tf.reduce_mean(tf.reduce_sum(tf.square((ys-l2)),reduction_indices = [1]))#需要向相加索引号,redeuc执行跨纬度操作 26 | 27 | train = tf.train.GradientDescentOptimizer(0.1).minimize(loss) # 选择梯度下降法 28 | 29 | init = tf.initialize_all_variables() 30 | sess = tf.Session() 31 | sess.run(init) 32 | 33 | for i in range(10000): 34 | sess.run(train,feed_dict={xs:x_data,ys:y_data}) 35 | if i%50 == 0: 36 | print (sess.run(loss,feed_dict={xs:x_data,ys:y_data})) -------------------------------------------------------------------------------- /BP神经网络/tensorflow_bp神经网络2.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import tensorflow as tf 3 | import numpy as np 4 | import matplotlib.pyplot as plt 5 | 6 | # Parameters 7 | learning_rate = 0.01 8 | num_steps = 1000 9 | batch_size = 100 10 | display_step = 100 11 | 12 | # Network Parameters 13 | n_hidden_1 = 10 # 1st layer number of neurons 14 | n_hidden_2 = 10 # 2nd layer number of neurons 15 | n_hidden_3 = 10 # 3rd layer number of neurons 16 | n_hidden_4 = 10 # 4th layer number of neurons 17 | n_hidden_5 = 10 # 5th layer number of neurons 18 | num_input = 2 # data input (img shape: 2) 19 | num_classes = 2 # total classes (2 digits) 20 | 21 | # tf Graph input 22 | X = tf.placeholder("float", [None, num_input]) 23 | Y = tf.placeholder("float", [None, num_classes]) 24 | 25 | # Store layers weight & bias 26 | with tf.name_scope('parameters'): 27 | weights = { 28 | 'h1': tf.Variable(tf.random_normal([num_input, n_hidden_1])), 29 | 'h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])), 30 | 'h3': tf.Variable(tf.random_normal([n_hidden_2, n_hidden_3])), 31 | 'h4': tf.Variable(tf.random_normal([n_hidden_3, n_hidden_4])), 32 | 'h5': tf.Variable(tf.random_normal([n_hidden_4, n_hidden_5])), 33 | 'out': tf.Variable(tf.random_normal([n_hidden_5, num_classes])) 34 | } 35 | biases = { 36 | 'b1': tf.Variable(tf.random_normal([n_hidden_1])), 37 | 'b2': tf.Variable(tf.random_normal([n_hidden_2])), 38 | 'b3': tf.Variable(tf.random_normal([n_hidden_3])), 39 | 'b4': tf.Variable(tf.random_normal([n_hidden_4])), 40 | 'b5': tf.Variable(tf.random_normal([n_hidden_5])), 41 | 'out': tf.Variable(tf.random_normal([num_classes])) 42 | } 43 | 44 | # Create model 45 | def neural_net(x): 46 | layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['h1']), biases['b1'])) 47 | 48 | layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['h2']), biases['b2'])) 49 | 50 | layer_3 = tf.nn.sigmoid(tf.add(tf.matmul(layer_2, weights['h3']), biases['b3'])) 51 | 52 | layer_4 = tf.nn.sigmoid(tf.add(tf.matmul(layer_3, weights['h4']), biases['b4'])) 53 | 54 | layer_5 = tf.nn.sigmoid(tf.add(tf.matmul(layer_4, weights['h5']), biases['b5'])) 55 | 56 | out_layer = tf.matmul(layer_5, weights['out']) + biases['out'] 57 | return out_layer 58 | 59 | def classifier(x,y): 60 | # input the expression you want 61 | if x**2+y**2<0.1 or 5*(x-1.1)**4poss[0,1]: 123 | ZZ[i,j]=1 124 | if classifier(inp[0,0],inp[0,1]): 125 | rightsum+=1 126 | else: 127 | ZZ[i,j]=0 128 | if classifier(inp[0,0],inp[0,1])==False: 129 | rightsum+=1 130 | print('Testing Accuracy',rightsum/100,'%') 131 | plt.contourf(XX,YY,ZZ,2,colors=('r','w','b')) 132 | 133 | 134 | # https://blog.csdn.net/Cfather/article/details/79254717 135 | -------------------------------------------------------------------------------- /BP神经网络/遗传算法优化的BP神经网络.py: -------------------------------------------------------------------------------- 1 | from operator import itemgetter, attrgetter 2 | import math 3 | import random 4 | import string 5 | import timeit 6 | from timeit import Timer as t 7 | import matplotlib.pyplot as plt 8 | import numpy as np 9 | 10 | def sigmoid (x): 11 | return math.tanh(x) 12 | 13 | def makeMatrix ( I, J, fill=0.0): 14 | m = [] 15 | for i in range(I): 16 | m.append([fill]*J) 17 | return m 18 | 19 | def randomizeMatrix ( matrix, a, b): 20 | for i in range ( len (matrix) ): 21 | for j in range ( len (matrix[0]) ): 22 | matrix[i][j] = random.uniform(a,b) 23 | 24 | class NN: 25 | def __init__(self, NI, NH, NO): 26 | self.ni = NI 27 | self.nh = NH 28 | self.no = NO 29 | self.ai = [1.0]*self.ni 30 | self.ah = [1.0]*self.nh 31 | self.ao = [1.0]*self.no 32 | self.wi = [ [0.0]*self.nh for i in range(self.ni) ] 33 | self.wo = [ [0.0]*self.no for j in range(self.nh) ] 34 | randomizeMatrix ( self.wi, -0.2, 0.2 ) 35 | randomizeMatrix ( self.wo, -2.0, 2.0 ) 36 | 37 | def runNN (self, inputs): 38 | if len(inputs) != self.ni: 39 | print ('incorrect number of inputs') 40 | for i in range(self.ni): 41 | self.ai[i] = inputs[i] 42 | for j in range(self.nh): 43 | self.ah[j] = sigmoid(sum([ self.ai[i]*self.wi[i][j] for i in range(self.ni) ])) 44 | for k in range(self.no): 45 | self.ao[k] = sigmoid(sum([ self.ah[j]*self.wo[j][k] for j in range(self.nh) ])) 46 | return self.ao 47 | 48 | def weights(self): 49 | print ('Input weights:') 50 | for i in range(self.ni): 51 | print (self.wi[i]) 52 | print () 53 | print ('Output weights:') 54 | for j in range(self.nh): 55 | print (self.wo[j]) 56 | print ('') 57 | 58 | def test(self, patterns): 59 | results, targets = [], [] 60 | for p in patterns: 61 | inputs = p[0] 62 | rounded = [ round(i) for i in self.runNN(inputs) ] 63 | if rounded == p[1]: result = '+++++' 64 | else: result = '-----' 65 | print ('%s %s %s %s %s %s %s' %( 'Inputs:', p[0], '-->', str(self.runNN(inputs)).rjust(65), 'Target', p[1], result)) 66 | results+= self.runNN(inputs) 67 | targets += p[1] 68 | return results, targets 69 | 70 | def sumErrors (self): 71 | error = 0.0 72 | for p in pat: 73 | inputs = p[0] 74 | targets = p[1] 75 | self.runNN(inputs) 76 | error += self.calcError(targets) 77 | inverr = 1.0/error 78 | return inverr 79 | 80 | def calcError (self, targets): 81 | error = 0.0 82 | for k in range(len(targets)): 83 | error += 0.5 * (targets[k]-self.ao[k])**2 84 | return error 85 | 86 | def assignWeights (self, weights, I): 87 | io = 0 88 | for i in range(self.ni): 89 | for j in range(self.nh): 90 | self.wi[i][j] = weights[I][io][i][j] 91 | io = 1 92 | for j in range(self.nh): 93 | for k in range(self.no): 94 | self.wo[j][k] = weights[I][io][j][k] 95 | 96 | def testWeights (self, weights, I): 97 | same = [] 98 | io = 0 99 | for i in range(self.ni): 100 | for j in range(self.nh): 101 | if self.wi[i][j] != weights[I][io][i][j]: 102 | same.append(('I',i,j, round(self.wi[i][j],2),round(weights[I][io][i][j],2),round(self.wi[i][j] - weights[I][io][i][j],2))) 103 | 104 | io = 1 105 | for j in range(self.nh): 106 | for k in range(self.no): 107 | if self.wo[j][k] != weights[I][io][j][k]: 108 | same.append((('O',j,k), round(self.wo[j][k],2),round(weights[I][io][j][k],2),round(self.wo[j][k] - weights[I][io][j][k],2))) 109 | if same != []: 110 | print (same) 111 | 112 | def roulette (fitnessScores): 113 | cumalativeFitness = 0.0 114 | r = random.random() 115 | for i in range(len(fitnessScores)): 116 | cumalativeFitness += fitnessScores[i] 117 | if cumalativeFitness > r: 118 | return i 119 | 120 | def calcFit (numbers): # each fitness is a fraction of the total error 121 | total, fitnesses = sum(numbers), [] 122 | for i in range(len(numbers)): 123 | fitnesses.append(numbers[i]/total) 124 | return fitnesses 125 | 126 | # takes a population of NN objects 127 | def pairPop (pop): 128 | weights, errors = [], [] 129 | for i in range(len(pop)): # for each individual 130 | weights.append([pop[i].wi,pop[i].wo]) # append input & output weights of individual to list of all pop weights 131 | errors.append(pop[i].sumErrors()) # append 1/sum(MSEs) of individual to list of pop errors 132 | fitnesses = calcFit(errors) # fitnesses are a fraction of the total error 133 | for i in range(int(pop_size*0.15)): 134 | print (str(i).zfill(2), '1/sum(MSEs)', str(errors[i]).rjust(15), str(int(errors[i]*graphical_error_scale)*'-').rjust(20), 'fitness'.rjust(12), str(fitnesses[i]).rjust(17), str(int(fitnesses[i]*1000)*'-').rjust(20)) 135 | del pop 136 | return zip(weights, errors,fitnesses) # weights become item[0] and fitnesses[1] in this way fitness is paired with its weight in a tuple 137 | 138 | def rankPop (newpopW,pop): 139 | errors, copy = [], [] # a fresh pop of NN's are assigned to a list of len pop_size 140 | #pop = [NN(ni,nh,no)]*pop_size # this does not work as they are all copies of eachother 141 | pop = [NN(ni,nh,no) for i in range(pop_size) ] 142 | for i in range(pop_size): copy.append(newpopW[i]) 143 | for i in range(pop_size): 144 | pop[i].assignWeights(newpopW, i) # each individual is assigned the weights generated from previous iteration 145 | pop[i].testWeights(newpopW, i) 146 | for i in range(pop_size): 147 | pop[i].testWeights(newpopW, i) 148 | pairedPop = pairPop(pop) # the fitness of these weights is calculated and tupled with the weights 149 | rankedPop = sorted(pairedPop, key = itemgetter(-1), reverse = True) # weights are sorted in descending order of fitness (fittest first) 150 | errors = [ eval(repr(x[1])) for x in rankedPop ] 151 | return rankedPop, eval(repr(rankedPop[0][1])), float(sum(errors))/float(len(errors)) 152 | 153 | def iteratePop (rankedPop): 154 | rankedWeights = [ item[0] for item in rankedPop] 155 | fitnessScores = [ item[-1] for item in rankedPop] 156 | newpopW = [ eval(repr(x)) for x in rankedWeights[:int(pop_size*0.15)] ] 157 | while len(newpopW) <= pop_size: # Breed two randomly selected but different chromos until pop_size reached 158 | ch1, ch2 = [], [] 159 | index1 = roulette(fitnessScores) 160 | index2 = roulette(fitnessScores) 161 | while index1 == index2: # ensures different chromos are used for breeeding 162 | index2 = roulette(fitnessScores) 163 | #index1, index2 = 3,4 164 | ch1.extend(eval(repr(rankedWeights[index1]))) 165 | ch2.extend(eval(repr(rankedWeights[index2]))) 166 | if random.random() < crossover_rate: 167 | ch1, ch2 = crossover(ch1, ch2) 168 | mutate(ch1) 169 | mutate(ch2) 170 | newpopW.append(ch1) 171 | newpopW.append(ch2) 172 | return newpopW 173 | 174 | graphical_error_scale = 100 175 | max_iterations = 4000 176 | pop_size = 100 177 | mutation_rate = 0.1 178 | crossover_rate = 0.8 179 | ni, nh, no = 4,6,1 180 | 181 | def main (): 182 | # Rank first random population 183 | pop = [ NN(ni,nh,no) for i in range(pop_size) ] # fresh pop 184 | pairedPop = pairPop(pop) 185 | rankedPop = sorted(pairedPop, key = itemgetter(-1), reverse = True) # THIS IS CORRECT 186 | # Keep iterating new pops until max_iterations 187 | iters = 0 188 | tops, avgs = [], [] 189 | while iters != max_iterations: 190 | if iters%1 == 0: 191 | print ('Iteration'.rjust(150), iters) 192 | newpopW = iteratePop(rankedPop) 193 | rankedPop, toperr, avgerr = rankPop(newpopW,pop) 194 | tops.append(toperr) 195 | avgs.append(avgerr) 196 | iters+=1 197 | 198 | # test a NN with the fittest weights 199 | tester = NN (ni,nh,no) 200 | fittestWeights = [ x[0] for x in rankedPop ] 201 | tester.assignWeights(fittestWeights, 0) 202 | results, targets = tester.test(testpat) 203 | x = np.arange(0,150) 204 | title2 = 'Test after '+str(iters)+' iterations' 205 | plt.title(title2) 206 | plt.ylabel('Node output') 207 | plt.xlabel('Instances') 208 | plt.plot( results, 'xr', linewidth = 0.5) 209 | plt.plot( targets, 's', color = 'black',linewidth = 3) 210 | #lines = plt.plot( results, 'sg') 211 | plt.annotate(s='Target Values', xy = (110, 0),color = 'black', family = 'sans-serif', size ='small') 212 | plt.annotate(s='Test Values', xy = (110, 0.5),color = 'red', family = 'sans-serif', size ='small', weight = 'bold') 213 | plt.figure(2) 214 | plt.subplot(121) 215 | plt.title('Top individual error evolution') 216 | plt.ylabel('Inverse error') 217 | plt.xlabel('Iterations') 218 | plt.plot( tops, '-g', linewidth = 1) 219 | plt.subplot(122) 220 | plt.plot( avgs, '-g', linewidth = 1) 221 | plt.title('Population average error evolution') 222 | plt.ylabel('Inverse error') 223 | plt.xlabel('Iterations') 224 | 225 | plt.show() 226 | 227 | print ('max_iterations',max_iterations,'\tpop_size',pop_size,'pop_size*0.15',int(pop_size*0.15),'\tmutation_rate',mutation_rate,'crossover_rate',crossover_rate,'ni, nh, no',ni, nh, no) 228 | 229 | def crossover (m1, m2): 230 | r = random.randint(0, (ni*nh)+(nh*no) ) # ni*nh+nh*no = total weights 231 | output1 = [ [[0.0]*nh]*ni ,[[0.0]*no]*nh ] 232 | output2 = [ [[0.0]*nh]*ni ,[[0.0]*no]*nh ] 233 | for i in range(len(m1)): 234 | for j in range(len(m1[i])): 235 | for k in range(len(m1[i][j])): 236 | if r >= 0: 237 | output1[i][j][k] = m1[i][j][k] 238 | output2[i][j][k] = m2[i][j][k] 239 | elif r < 0: 240 | output1[i][j][k] = m2[i][j][k] 241 | output2[i][j][k] = m1[i][j][k] 242 | r -=1 243 | return output1, output2 244 | 245 | def mutate (m): 246 | # could include a constant to control 247 | # how much the weight is mutated by 248 | for i in range(len(m)): 249 | for j in range(len(m[i])): 250 | for k in range(len(m[i][j])): 251 | if random.random() < mutation_rate: 252 | m[i][j][k] = random.uniform(-2.0,2.0) 253 | 254 | if __name__ == "__main__": 255 | 256 | pat = [ 257 | [[5.1, 3.5, 1.4, 0.2], [-1], ['Iris-setosa']] , 258 | [[4.9, 3.0, 1.4, 0.2], [-1], ['Iris-setosa']] , 259 | [[4.7, 3.2, 1.3, 0.2], [-1], ['Iris-setosa']] , 260 | [[5.4, 3.9, 1.7, 0.4], [-1], ['Iris-setosa']] , 261 | [[4.6, 3.4, 1.4, 0.3], [-1], ['Iris-setosa']] , 262 | [[5.0, 3.4, 1.5, 0.2], [-1], ['Iris-setosa']] , 263 | [[4.4, 2.9, 1.4, 0.2], [-1], ['Iris-setosa']] , 264 | [[4.9, 3.1, 1.5, 0.1], [-1], ['Iris-setosa']] , 265 | [[5.4, 3.7, 1.5, 0.2], [-1], ['Iris-setosa']] , 266 | [[4.8, 3.4, 1.6, 0.2], [-1], ['Iris-setosa']] , 267 | [[4.8, 3.0, 1.4, 0.1], [-1], ['Iris-setosa']] , 268 | [[4.3, 3.0, 1.1, 0.1], [-1], ['Iris-setosa']] , 269 | [[5.8, 4.0, 1.2, 0.2], [-1], ['Iris-setosa']] , 270 | [[5.7, 4.4, 1.5, 0.4], [-1], ['Iris-setosa']] , 271 | [[5.4, 3.9, 1.3, 0.4], [-1], ['Iris-setosa']] , 272 | [[5.1, 3.5, 1.4, 0.3], [-1], ['Iris-setosa']] , 273 | [[5.7, 3.8, 1.7, 0.3], [-1], ['Iris-setosa']] , 274 | [[5.1, 3.8, 1.5, 0.3], [-1], ['Iris-setosa']] , 275 | [[5.4, 3.4, 1.7, 0.2], [-1], ['Iris-setosa']] , 276 | [[5.1, 3.7, 1.5, 0.4], [-1], ['Iris-setosa']] , 277 | [[4.6, 3.6, 1.0, 0.2], [-1], ['Iris-setosa']] , 278 | [[5.1, 3.3, 1.7, 0.5], [-1], ['Iris-setosa']] , 279 | [[4.8, 3.4, 1.9, 0.2], [-1], ['Iris-setosa']] , 280 | [[5.0, 3.0, 1.6, 0.2], [-1], ['Iris-setosa']] , 281 | [[5.0, 3.4, 1.6, 0.4], [-1], ['Iris-setosa']] , 282 | [[5.2, 3.5, 1.5, 0.2], [-1], ['Iris-setosa']] , 283 | [[5.2, 3.4, 1.4, 0.2], [-1], ['Iris-setosa']] , 284 | [[4.7, 3.2, 1.6, 0.2], [-1], ['Iris-setosa']] , 285 | [[4.8, 3.1, 1.6, 0.2], [-1], ['Iris-setosa']] , 286 | [[5.4, 3.4, 1.5, 0.4], [-1], ['Iris-setosa']] , 287 | [[5.2, 4.1, 1.5, 0.1], [-1], ['Iris-setosa']] , 288 | [[5.5, 4.2, 1.4, 0.2], [-1], ['Iris-setosa']] , 289 | [[4.9, 3.1, 1.5, 0.1], [-1], ['Iris-setosa']] , 290 | [[5.0, 3.2, 1.2, 0.2], [-1], ['Iris-setosa']] , 291 | [[5.5, 3.5, 1.3, 0.2], [-1], ['Iris-setosa']] , 292 | [[4.9, 3.1, 1.5, 0.1], [-1], ['Iris-setosa']] , 293 | [[4.4, 3.0, 1.3, 0.2], [-1], ['Iris-setosa']] , 294 | [[5.1, 3.4, 1.5, 0.2], [-1], ['Iris-setosa']] , 295 | [[5.0, 3.5, 1.3, 0.3], [-1], ['Iris-setosa']] , 296 | [[4.5, 2.3, 1.3, 0.3], [-1], ['Iris-setosa']] , 297 | [[4.4, 3.2, 1.3, 0.2], [-1], ['Iris-setosa']] , 298 | [[5.0, 3.5, 1.6, 0.6], [-1], ['Iris-setosa']] , 299 | [[5.1, 3.8, 1.9, 0.4], [-1], ['Iris-setosa']] , 300 | [[4.8, 3.0, 1.4, 0.3], [-1], ['Iris-setosa']] , 301 | [[5.1, 3.8, 1.6, 0.2], [-1], ['Iris-setosa']] , 302 | [[4.6, 3.2, 1.4, 0.2], [-1], ['Iris-setosa']] , 303 | [[5.3, 3.7, 1.5, 0.2], [-1], ['Iris-setosa']] , 304 | [[5.0, 3.3, 1.4, 0.2], [-1], ['Iris-setosa']] , 305 | [[7.0, 3.2, 4.7, 1.4], [0], ['Iris-versicolor']] , 306 | [[6.4, 3.2, 4.5, 1.5], [0], ['Iris-versicolor']] , 307 | [[6.9, 3.1, 4.9, 1.5], [0], ['Iris-versicolor']] , 308 | [[5.5, 2.3, 4.0, 1.3], [0], ['Iris-versicolor']] , 309 | [[6.5, 2.8, 4.6, 1.5], [0], ['Iris-versicolor']] , 310 | [[5.7, 2.8, 4.5, 1.3], [0], ['Iris-versicolor']] , 311 | [[6.3, 3.3, 4.7, 1.6], [0], ['Iris-versicolor']] , 312 | [[4.9, 2.4, 3.3, 1.0], [0], ['Iris-versicolor']] , 313 | [[6.6, 2.9, 4.6, 1.3], [0], ['Iris-versicolor']] , 314 | [[5.2, 2.7, 3.9, 1.4], [0], ['Iris-versicolor']] , 315 | [[5.0, 2.0, 3.5, 1.0], [0], ['Iris-versicolor']] , 316 | [[5.9, 3.0, 4.2, 1.5], [0], ['Iris-versicolor']] , 317 | [[6.0, 2.2, 4.0, 1.0], [0], ['Iris-versicolor']] , 318 | [[6.1, 2.9, 4.7, 1.4], [0], ['Iris-versicolor']] , 319 | [[5.6, 2.9, 3.6, 1.3], [0], ['Iris-versicolor']] , 320 | [[6.7, 3.1, 4.4, 1.4], [0], ['Iris-versicolor']] , 321 | [[5.6, 3.0, 4.5, 1.5], [0], ['Iris-versicolor']] , 322 | [[5.8, 2.7, 4.1, 1.0], [0], ['Iris-versicolor']] , 323 | [[6.2, 2.2, 4.5, 1.5], [0], ['Iris-versicolor']] , 324 | [[5.6, 2.5, 3.9, 1.1], [0], ['Iris-versicolor']] , 325 | [[5.9, 3.2, 4.8, 1.8], [0], ['Iris-versicolor']] , 326 | [[6.1, 2.8, 4.0, 1.3], [0], ['Iris-versicolor']] , 327 | [[6.3, 2.5, 4.9, 1.5], [0], ['Iris-versicolor']] , 328 | [[6.1, 2.8, 4.7, 1.2], [0], ['Iris-versicolor']] , 329 | [[6.4, 2.9, 4.3, 1.3], [0], ['Iris-versicolor']] , 330 | [[6.6, 3.0, 4.4, 1.4], [0], ['Iris-versicolor']] , 331 | [[6.8, 2.8, 4.8, 1.4], [0], ['Iris-versicolor']] , 332 | [[6.7, 3.0, 5.0, 1.7], [0], ['Iris-versicolor']] , 333 | [[6.0, 2.9, 4.5, 1.5], [0], ['Iris-versicolor']] , 334 | [[5.7, 2.6, 3.5, 1.0], [0], ['Iris-versicolor']] , 335 | [[5.5, 2.4, 3.8, 1.1], [0], ['Iris-versicolor']] , 336 | [[5.5, 2.4, 3.7, 1.0], [0], ['Iris-versicolor']] , 337 | [[5.8, 2.7, 3.9, 1.2], [0], ['Iris-versicolor']] , 338 | [[6.0, 2.7, 5.1, 1.6], [0], ['Iris-versicolor']] , 339 | [[5.4, 3.0, 4.5, 1.5], [0], ['Iris-versicolor']] , 340 | [[6.0, 3.4, 4.5, 1.6], [0], ['Iris-versicolor']] , 341 | [[6.7, 3.1, 4.7, 1.5], [0], ['Iris-versicolor']] , 342 | [[6.3, 2.3, 4.4, 1.3], [0], ['Iris-versicolor']] , 343 | [[5.6, 3.0, 4.1, 1.3], [0], ['Iris-versicolor']] , 344 | [[6.1, 3.0, 4.6, 1.4], [0], ['Iris-versicolor']] , 345 | [[5.8, 2.6, 4.0, 1.2], [0], ['Iris-versicolor']] , 346 | [[5.0, 2.3, 3.3, 1.0], [0], ['Iris-versicolor']] , 347 | [[5.6, 2.7, 4.2, 1.3], [0], ['Iris-versicolor']] , 348 | [[5.7, 3.0, 4.2, 1.2], [0], ['Iris-versicolor']] , 349 | [[5.7, 2.9, 4.2, 1.3], [0], ['Iris-versicolor']] , 350 | [[6.2, 2.9, 4.3, 1.3], [0], ['Iris-versicolor']] , 351 | [[5.1, 2.5, 3.0, 1.1], [0], ['Iris-versicolor']] , 352 | [[5.7, 2.8, 4.1, 1.3], [0], ['Iris-versicolor']] , 353 | [[6.3, 3.3, 6.0, 2.5], [1], ['Iris-virginica']] , 354 | [[5.8, 2.7, 5.1, 1.9], [1], ['Iris-virginica']] , 355 | [[7.1, 3.0, 5.9, 2.1], [1], ['Iris-virginica']] , 356 | [[6.3, 2.9, 5.6, 1.8], [1], ['Iris-virginica']] , 357 | [[6.5, 3.0, 5.8, 2.2], [1], ['Iris-virginica']] , 358 | [[7.6, 3.0, 6.6, 2.1], [1], ['Iris-virginica']] , 359 | [[4.9, 2.5, 4.5, 1.7], [1], ['Iris-virginica']] , 360 | [[7.3, 2.9, 6.3, 1.8], [1], ['Iris-virginica']] , 361 | [[6.7, 2.5, 5.8, 1.8], [1], ['Iris-virginica']] , 362 | [[7.2, 3.6, 6.1, 2.5], [1], ['Iris-virginica']] , 363 | [[6.5, 3.2, 5.1, 2.0], [1], ['Iris-virginica']] , 364 | [[6.4, 2.7, 5.3, 1.9], [1], ['Iris-virginica']] , 365 | [[6.8, 3.0, 5.5, 2.1], [1], ['Iris-virginica']] , 366 | [[5.7, 2.5, 5.0, 2.0], [1], ['Iris-virginica']] , 367 | [[5.8, 2.8, 5.1, 2.4], [1], ['Iris-virginica']] , 368 | [[7.7, 3.8, 6.7, 2.2], [1], ['Iris-virginica']] , 369 | [[7.7, 2.6, 6.9, 2.3], [1], ['Iris-virginica']] , 370 | [[6.0, 2.2, 5.0, 1.5], [1], ['Iris-virginica']] , 371 | [[6.9, 3.2, 5.7, 2.3], [1], ['Iris-virginica']] , 372 | [[5.6, 2.8, 4.9, 2.0], [1], ['Iris-virginica']] , 373 | [[7.7, 2.8, 6.7, 2.0], [1], ['Iris-virginica']] , 374 | [[6.3, 2.7, 4.9, 1.8], [1], ['Iris-virginica']] , 375 | [[6.7, 3.3, 5.7, 2.1], [1], ['Iris-virginica']] , 376 | [[7.2, 3.2, 6.0, 1.8], [1], ['Iris-virginica']] , 377 | [[6.2, 2.8, 4.8, 1.8], [1], ['Iris-virginica']] , 378 | [[6.1, 3.0, 4.9, 1.8], [1], ['Iris-virginica']] , 379 | [[6.4, 2.8, 5.6, 2.1], [1], ['Iris-virginica']] , 380 | [[7.2, 3.0, 5.8, 1.6], [1], ['Iris-virginica']] , 381 | [[7.4, 2.8, 6.1, 1.9], [1], ['Iris-virginica']] , 382 | [[7.9, 3.8, 6.4, 2.0], [1], ['Iris-virginica']] , 383 | [[6.4, 2.8, 5.6, 2.2], [1], ['Iris-virginica']] , 384 | [[6.3, 2.8, 5.1, 1.5], [1], ['Iris-virginica']] , 385 | [[6.1, 2.6, 5.6, 1.4], [1], ['Iris-virginica']] , 386 | [[7.7, 3.0, 6.1, 2.3], [1], ['Iris-virginica']] , 387 | [[6.3, 3.4, 5.6, 2.4], [1], ['Iris-virginica']] , 388 | [[6.4, 3.1, 5.5, 1.8], [1], ['Iris-virginica']] , 389 | [[6.0, 3.0, 4.8, 1.8], [1], ['Iris-virginica']] , 390 | [[6.9, 3.1, 5.4, 2.1], [1], ['Iris-virginica']] , 391 | [[6.7, 3.1, 5.6, 2.4], [1], ['Iris-virginica']] , 392 | [[6.9, 3.1, 5.1, 2.3], [1], ['Iris-virginica']] , 393 | [[5.8, 2.7, 5.1, 1.9], [1], ['Iris-virginica']] , 394 | [[6.8, 3.2, 5.9, 2.3], [1], ['Iris-virginica']] , 395 | [[6.7, 3.3, 5.7, 2.5], [1], ['Iris-virginica']] , 396 | [[6.7, 3.0, 5.2, 2.3], [1], ['Iris-virginica']] , 397 | [[6.3, 2.5, 5.0, 1.9], [1], ['Iris-virginica']] , 398 | [[6.5, 3.0, 5.2, 2.0], [1], ['Iris-virginica']] , 399 | [[6.2, 3.4, 5.4, 2.3], [1], ['Iris-virginica']] , 400 | [[5.9, 3.0, 5.1, 1.8], [1], ['Iris-virginica']] 401 | ] 402 | 403 | testpat = [ 404 | [[5.1, 3.5, 1.4, 0.2], [-1], ['Iris-setosa']] , 405 | [[4.9, 3.0, 1.4, 0.2], [-1], ['Iris-setosa']] , 406 | [[4.7, 3.2, 1.3, 0.2], [-1], ['Iris-setosa']] , 407 | [[5.4, 3.9, 1.7, 0.4], [-1], ['Iris-setosa']] , 408 | [[4.6, 3.4, 1.4, 0.3], [-1], ['Iris-setosa']] , 409 | [[5.0, 3.4, 1.5, 0.2], [-1], ['Iris-setosa']] , 410 | [[4.4, 2.9, 1.4, 0.2], [-1], ['Iris-setosa']] , 411 | [[4.9, 3.1, 1.5, 0.1], [-1], ['Iris-setosa']] , 412 | [[5.4, 3.7, 1.5, 0.2], [-1], ['Iris-setosa']] , 413 | [[4.8, 3.4, 1.6, 0.2], [-1], ['Iris-setosa']] , 414 | [[4.8, 3.0, 1.4, 0.1], [-1], ['Iris-setosa']] , 415 | [[4.3, 3.0, 1.1, 0.1], [-1], ['Iris-setosa']] , 416 | [[5.8, 4.0, 1.2, 0.2], [-1], ['Iris-setosa']] , 417 | [[5.7, 4.4, 1.5, 0.4], [-1], ['Iris-setosa']] , 418 | [[5.4, 3.9, 1.3, 0.4], [-1], ['Iris-setosa']] , 419 | [[5.1, 3.5, 1.4, 0.3], [-1], ['Iris-setosa']] , 420 | [[5.7, 3.8, 1.7, 0.3], [-1], ['Iris-setosa']] , 421 | [[5.1, 3.8, 1.5, 0.3], [-1], ['Iris-setosa']] , 422 | [[5.4, 3.4, 1.7, 0.2], [-1], ['Iris-setosa']] , 423 | [[5.1, 3.7, 1.5, 0.4], [-1], ['Iris-setosa']] , 424 | [[4.6, 3.6, 1.0, 0.2], [-1], ['Iris-setosa']] , 425 | [[5.1, 3.3, 1.7, 0.5], [-1], ['Iris-setosa']] , 426 | [[4.8, 3.4, 1.9, 0.2], [-1], ['Iris-setosa']] , 427 | [[5.0, 3.0, 1.6, 0.2], [-1], ['Iris-setosa']] , 428 | [[5.0, 3.4, 1.6, 0.4], [-1], ['Iris-setosa']] , 429 | [[5.2, 3.5, 1.5, 0.2], [-1], ['Iris-setosa']] , 430 | [[5.2, 3.4, 1.4, 0.2], [-1], ['Iris-setosa']] , 431 | [[4.7, 3.2, 1.6, 0.2], [-1], ['Iris-setosa']] , 432 | [[4.8, 3.1, 1.6, 0.2], [-1], ['Iris-setosa']] , 433 | [[5.4, 3.4, 1.5, 0.4], [-1], ['Iris-setosa']] , 434 | [[5.2, 4.1, 1.5, 0.1], [-1], ['Iris-setosa']] , 435 | [[5.5, 4.2, 1.4, 0.2], [-1], ['Iris-setosa']] , 436 | [[4.9, 3.1, 1.5, 0.1], [-1], ['Iris-setosa']] , 437 | [[5.0, 3.2, 1.2, 0.2], [-1], ['Iris-setosa']] , 438 | [[5.5, 3.5, 1.3, 0.2], [-1], ['Iris-setosa']] , 439 | [[4.9, 3.1, 1.5, 0.1], [-1], ['Iris-setosa']] , 440 | [[4.4, 3.0, 1.3, 0.2], [-1], ['Iris-setosa']] , 441 | [[5.1, 3.4, 1.5, 0.2], [-1], ['Iris-setosa']] , 442 | [[5.0, 3.5, 1.3, 0.3], [-1], ['Iris-setosa']] , 443 | [[4.5, 2.3, 1.3, 0.3], [-1], ['Iris-setosa']] , 444 | [[4.4, 3.2, 1.3, 0.2], [-1], ['Iris-setosa']] , 445 | [[5.0, 3.5, 1.6, 0.6], [-1], ['Iris-setosa']] , 446 | [[5.1, 3.8, 1.9, 0.4], [-1], ['Iris-setosa']] , 447 | [[4.8, 3.0, 1.4, 0.3], [-1], ['Iris-setosa']] , 448 | [[5.1, 3.8, 1.6, 0.2], [-1], ['Iris-setosa']] , 449 | [[4.6, 3.2, 1.4, 0.2], [-1], ['Iris-setosa']] , 450 | [[5.3, 3.7, 1.5, 0.2], [-1], ['Iris-setosa']] , 451 | [[5.0, 3.3, 1.4, 0.2], [-1], ['Iris-setosa']] , 452 | [[7.0, 3.2, 4.7, 1.4], [0], ['Iris-versicolor']] , 453 | [[6.4, 3.2, 4.5, 1.5], [0], ['Iris-versicolor']] , 454 | [[6.9, 3.1, 4.9, 1.5], [0], ['Iris-versicolor']] , 455 | [[5.5, 2.3, 4.0, 1.3], [0], ['Iris-versicolor']] , 456 | [[6.5, 2.8, 4.6, 1.5], [0], ['Iris-versicolor']] , 457 | [[5.7, 2.8, 4.5, 1.3], [0], ['Iris-versicolor']] , 458 | [[6.3, 3.3, 4.7, 1.6], [0], ['Iris-versicolor']] , 459 | [[4.9, 2.4, 3.3, 1.0], [0], ['Iris-versicolor']] , 460 | [[6.6, 2.9, 4.6, 1.3], [0], ['Iris-versicolor']] , 461 | [[5.2, 2.7, 3.9, 1.4], [0], ['Iris-versicolor']] , 462 | [[5.0, 2.0, 3.5, 1.0], [0], ['Iris-versicolor']] , 463 | [[5.9, 3.0, 4.2, 1.5], [0], ['Iris-versicolor']] , 464 | [[6.0, 2.2, 4.0, 1.0], [0], ['Iris-versicolor']] , 465 | [[6.1, 2.9, 4.7, 1.4], [0], ['Iris-versicolor']] , 466 | [[5.6, 2.9, 3.6, 1.3], [0], ['Iris-versicolor']] , 467 | [[6.7, 3.1, 4.4, 1.4], [0], ['Iris-versicolor']] , 468 | [[5.6, 3.0, 4.5, 1.5], [0], ['Iris-versicolor']] , 469 | [[5.8, 2.7, 4.1, 1.0], [0], ['Iris-versicolor']] , 470 | [[6.2, 2.2, 4.5, 1.5], [0], ['Iris-versicolor']] , 471 | [[5.6, 2.5, 3.9, 1.1], [0], ['Iris-versicolor']] , 472 | [[5.9, 3.2, 4.8, 1.8], [0], ['Iris-versicolor']] , 473 | [[6.1, 2.8, 4.0, 1.3], [0], ['Iris-versicolor']] , 474 | [[6.3, 2.5, 4.9, 1.5], [0], ['Iris-versicolor']] , 475 | [[6.1, 2.8, 4.7, 1.2], [0], ['Iris-versicolor']] , 476 | [[6.4, 2.9, 4.3, 1.3], [0], ['Iris-versicolor']] , 477 | [[6.6, 3.0, 4.4, 1.4], [0], ['Iris-versicolor']] , 478 | [[6.8, 2.8, 4.8, 1.4], [0], ['Iris-versicolor']] , 479 | [[6.7, 3.0, 5.0, 1.7], [0], ['Iris-versicolor']] , 480 | [[6.0, 2.9, 4.5, 1.5], [0], ['Iris-versicolor']] , 481 | [[5.7, 2.6, 3.5, 1.0], [0], ['Iris-versicolor']] , 482 | [[5.5, 2.4, 3.8, 1.1], [0], ['Iris-versicolor']] , 483 | [[5.5, 2.4, 3.7, 1.0], [0], ['Iris-versicolor']] , 484 | [[5.8, 2.7, 3.9, 1.2], [0], ['Iris-versicolor']] , 485 | [[6.0, 2.7, 5.1, 1.6], [0], ['Iris-versicolor']] , 486 | [[5.4, 3.0, 4.5, 1.5], [0], ['Iris-versicolor']] , 487 | [[6.0, 3.4, 4.5, 1.6], [0], ['Iris-versicolor']] , 488 | [[6.7, 3.1, 4.7, 1.5], [0], ['Iris-versicolor']] , 489 | [[6.3, 2.3, 4.4, 1.3], [0], ['Iris-versicolor']] , 490 | [[5.6, 3.0, 4.1, 1.3], [0], ['Iris-versicolor']] , 491 | [[6.1, 3.0, 4.6, 1.4], [0], ['Iris-versicolor']] , 492 | [[5.8, 2.6, 4.0, 1.2], [0], ['Iris-versicolor']] , 493 | [[5.0, 2.3, 3.3, 1.0], [0], ['Iris-versicolor']] , 494 | [[5.6, 2.7, 4.2, 1.3], [0], ['Iris-versicolor']] , 495 | [[5.7, 3.0, 4.2, 1.2], [0], ['Iris-versicolor']] , 496 | [[5.7, 2.9, 4.2, 1.3], [0], ['Iris-versicolor']] , 497 | [[6.2, 2.9, 4.3, 1.3], [0], ['Iris-versicolor']] , 498 | [[5.1, 2.5, 3.0, 1.1], [0], ['Iris-versicolor']] , 499 | [[5.7, 2.8, 4.1, 1.3], [0], ['Iris-versicolor']] , 500 | [[6.3, 3.3, 6.0, 2.5], [1], ['Iris-virginica']] , 501 | [[5.8, 2.7, 5.1, 1.9], [1], ['Iris-virginica']] , 502 | [[7.1, 3.0, 5.9, 2.1], [1], ['Iris-virginica']] , 503 | [[6.3, 2.9, 5.6, 1.8], [1], ['Iris-virginica']] , 504 | [[6.5, 3.0, 5.8, 2.2], [1], ['Iris-virginica']] , 505 | [[7.6, 3.0, 6.6, 2.1], [1], ['Iris-virginica']] , 506 | [[4.9, 2.5, 4.5, 1.7], [1], ['Iris-virginica']] , 507 | [[7.3, 2.9, 6.3, 1.8], [1], ['Iris-virginica']] , 508 | [[6.7, 2.5, 5.8, 1.8], [1], ['Iris-virginica']] , 509 | [[7.2, 3.6, 6.1, 2.5], [1], ['Iris-virginica']] , 510 | [[6.5, 3.2, 5.1, 2.0], [1], ['Iris-virginica']] , 511 | [[6.4, 2.7, 5.3, 1.9], [1], ['Iris-virginica']] , 512 | [[6.8, 3.0, 5.5, 2.1], [1], ['Iris-virginica']] , 513 | [[5.7, 2.5, 5.0, 2.0], [1], ['Iris-virginica']] , 514 | [[5.8, 2.8, 5.1, 2.4], [1], ['Iris-virginica']] , 515 | [[7.7, 3.8, 6.7, 2.2], [1], ['Iris-virginica']] , 516 | [[7.7, 2.6, 6.9, 2.3], [1], ['Iris-virginica']] , 517 | [[6.0, 2.2, 5.0, 1.5], [1], ['Iris-virginica']] , 518 | [[6.9, 3.2, 5.7, 2.3], [1], ['Iris-virginica']] , 519 | [[5.6, 2.8, 4.9, 2.0], [1], ['Iris-virginica']] , 520 | [[7.7, 2.8, 6.7, 2.0], [1], ['Iris-virginica']] , 521 | [[6.3, 2.7, 4.9, 1.8], [1], ['Iris-virginica']] , 522 | [[6.7, 3.3, 5.7, 2.1], [1], ['Iris-virginica']] , 523 | [[7.2, 3.2, 6.0, 1.8], [1], ['Iris-virginica']] , 524 | [[6.2, 2.8, 4.8, 1.8], [1], ['Iris-virginica']] , 525 | [[6.1, 3.0, 4.9, 1.8], [1], ['Iris-virginica']] , 526 | [[6.4, 2.8, 5.6, 2.1], [1], ['Iris-virginica']] , 527 | [[7.2, 3.0, 5.8, 1.6], [1], ['Iris-virginica']] , 528 | [[7.4, 2.8, 6.1, 1.9], [1], ['Iris-virginica']] , 529 | [[7.9, 3.8, 6.4, 2.0], [1], ['Iris-virginica']] , 530 | [[6.4, 2.8, 5.6, 2.2], [1], ['Iris-virginica']] , 531 | [[6.3, 2.8, 5.1, 1.5], [1], ['Iris-virginica']] , 532 | [[6.1, 2.6, 5.6, 1.4], [1], ['Iris-virginica']] , 533 | [[7.7, 3.0, 6.1, 2.3], [1], ['Iris-virginica']] , 534 | [[6.3, 3.4, 5.6, 2.4], [1], ['Iris-virginica']] , 535 | [[6.4, 3.1, 5.5, 1.8], [1], ['Iris-virginica']] , 536 | [[6.0, 3.0, 4.8, 1.8], [1], ['Iris-virginica']] , 537 | [[6.9, 3.1, 5.4, 2.1], [1], ['Iris-virginica']] , 538 | [[6.7, 3.1, 5.6, 2.4], [1], ['Iris-virginica']] , 539 | [[6.9, 3.1, 5.1, 2.3], [1], ['Iris-virginica']] , 540 | [[5.8, 2.7, 5.1, 1.9], [1], ['Iris-virginica']] , 541 | [[6.8, 3.2, 5.9, 2.3], [1], ['Iris-virginica']] , 542 | [[6.7, 3.3, 5.7, 2.5], [1], ['Iris-virginica']] , 543 | [[6.7, 3.0, 5.2, 2.3], [1], ['Iris-virginica']] , 544 | [[6.3, 2.5, 5.0, 1.9], [1], ['Iris-virginica']] , 545 | [[6.5, 3.0, 5.2, 2.0], [1], ['Iris-virginica']] , 546 | [[6.2, 3.4, 5.4, 2.3], [1], ['Iris-virginica']] , 547 | [[5.9, 3.0, 5.1, 1.8], [1], ['Iris-virginica']] 548 | ] 549 | 550 | main() -------------------------------------------------------------------------------- /DNN/keras_dnn.py: -------------------------------------------------------------------------------- 1 | #由于不能链接到官方的已经处理好的数据,所以这里通过tensorflow导入mnist数据 2 | import tensorflow as tf 3 | from tensorflow.examples.tutorials.mnist import input_data 4 | #from _future_ import print_function 5 | import numpy as np 6 | #from keras.dataseets import mnist 7 | from keras.models import Sequential 8 | from keras.layers import Dense 9 | from keras.utils import np_utils 10 | 11 | batch_size = 128 #梯度下降一个批(batch)的数据量 12 | nb_classes =10 #类别 13 | nb_epoch =10 #梯度下降epoch循环训练次数,每次循环包含全部的样本 14 | image_size = 28*28 #输入图片的大小,由于是灰度图片,因此只有一个颜色通道 15 | 16 | #加载数据 17 | mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) 18 | x_train,y_train= mnist.train.images, mnist.train.labels 19 | #print(x_train.shape,y_train.shape) #(55000, 784) (55000, 10) 20 | x_test,y_test= mnist.test.images, mnist.test.labels 21 | #print(x_test.shape,y_test.shape) #(10000, 784) (10000, 10) 22 | #如果y_train\y_test不是one_hot编码,需要进行转换 23 | 24 | #创建模型,逻辑分类相当于一层全链接的神经网络(Dense是Keras中定义的DNN模型) 25 | model = Sequential([Dense(128,input_shape=(image_size,),activation= 'relu'),Dense(10,input_shape=(128,),activation= 'softmax')]) 26 | #配置优化器,损失函数 27 | model.compile(optimizer = 'rmsprop',loss = 'categorical_crossentropy',metrics= ['accuracy']) 28 | model.fit(x_train,y_train,batch_size = batch_size,nb_epoch = nb_epoch,verbose = 1,validation_data = (x_test,y_test)) 29 | #score分数包含两部分,一部分是val_loss,一部分是val_acc。取score[1]来进行模型的得分评价 30 | score = model.evaluate(x_test,y_test,verbose = 0) 31 | print('Accuracy:{}'.format(score[1])) -------------------------------------------------------------------------------- /DNN/tensorflow_DNN.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | 3 | #下载mnist数据集 4 | from tensorflow.examples.tutorials.mnist import input_data 5 | mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) 6 | 7 | import tensorflow as tf 8 | 9 | #定义一些参数 10 | learning_rate = 0.001 11 | train_epochs = 20 12 | batch_size = 64 13 | 14 | #定义3层感知机的神经单元个数 15 | n_input = 784 16 | n_hidden1 = 100 17 | n_hidden2 = 100 18 | n_classes = 10 19 | 20 | #定义网络输入参数占位符 21 | x = tf.placeholder(tf.float32, shape=[None, n_input]) 22 | y = tf.placeholder(tf.float32, shape=[None, n_classes]) 23 | 24 | #定义权重与偏置 25 | weights = {'h1': tf.Variable(tf.random_normal([n_input, n_hidden1])), 26 | 'h2': tf.Variable(tf.random_normal([n_hidden1, n_hidden2])), 27 | 'out': tf.Variable(tf.random_normal([n_hidden2, n_classes]))} 28 | 29 | biases = {'b1': tf.Variable(tf.random_normal([n_hidden1])), 30 | 'b2': tf.Variable(tf.random_normal([n_hidden2])), 31 | 'out': tf.Variable(tf.random_normal([n_classes]))} 32 | 33 | 34 | #定义推断过程 35 | def inference(input_x): 36 | layer_1 = tf.nn.relu(tf.matmul(x, weights['h1']) + biases['b1']) 37 | layer_2 = tf.nn.relu(tf.matmul(layer_1, weights['h2']) + biases['b2']) 38 | out_layer = tf.matmul(layer_2, weights['out']) + biases['out'] 39 | return out_layer 40 | 41 | #构建网络 42 | logits = inference(x) 43 | prediction = tf.nn.softmax(logits) 44 | 45 | #定义损失函数与优化器 46 | loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y)) 47 | optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate) 48 | train_op = optimizer.minimize(loss) 49 | 50 | #定义评价指标(准确度) 51 | pre_correct = tf.equal(tf.argmax(y, 1), tf.argmax(prediction, 1)) 52 | accuracy = tf.reduce_mean(tf.cast(pre_correct, tf.float32)) 53 | 54 | #初始化所有变量 55 | init = tf.global_variables_initializer() 56 | 57 | #开始训练 58 | with tf.Session() as sess: 59 | sess.run(init) 60 | total_batch = int(mnist.train.num_examples / batch_size) 61 | 62 | for epoch in range(train_epochs): 63 | for batch in range(total_batch): 64 | batch_x, batch_y = mnist.train.next_batch(batch_size) 65 | sess.run(train_op, feed_dict={x:batch_x, y:batch_y}) 66 | 67 | if epoch % 10 == 0: 68 | loss_, acc = sess.run([loss, accuracy], feed_dict={x:batch_x, y:batch_y}) 69 | print("epoch {}, loss {:.4f}, acc {:.3f}".format(epoch, loss_, acc)) 70 | 71 | print("optimizer finished!") 72 | 73 | #计算测试集的准确度 74 | test_acc = sess.run(accuracy, feed_dict={x:mnist.test.images, y:mnist.test.labels}) 75 | print('test accuracy', test_acc) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # My-TensorFlow-tutorials 2 | TensorFlow 学习笔记和分享,包含手写数字识别、猫狗识别和TensorFlow的一些基础学习代码。 3 | 4 | 如果需要数据包,请在 issues 中提问。 5 | 6 | * 手写数字识别 7 | 8 | 博客地址:http://blog.csdn.net/u012373815/article/details/77203316 9 | 10 | * 猫狗识别 11 | 12 | 博客地址:http://blog.csdn.net/u012373815/article/details/78768727 13 | 14 | * 验证码识别 (未完成) 15 | -------------------------------------------------------------------------------- /tensorflow.md: -------------------------------------------------------------------------------- 1 | ##TensorFlow 2 | TensorFlow 是一个编程系统, 使用图来表示计算任务. 图中的节点被称之为 op (operation 的缩写). 一个 op 获得 0 个或多个 Tensor, 执行计算, 产生 0 个或多个 Tensor. 每个 Tensor 是一个类型化的多维数组. 例如, 你可以将一小组图像集表示为一个四维浮点数数组, 这四个维度分别是 [batch, height, width, channels]. 3 | 4 | 一个 TensorFlow 图描述了计算的过程. 为了进行计算, 图必须在 会话 里被启动. 会话 将图的 op 分发到诸如 CPU 或 GPU 之类的 设备 上, 同时提供执行 op 的方法. 这些方法执行后, 将产生的 tensor 返回. 在 Python 语言中, 返回的 tensor 是 numpy ndarray 对象; 在 C 和 C++ 语言中, 返回的 tensor 是 tensorflow::Tensor 实例. 5 | 6 | 7 | 8 | TensorFlow的一个基本的功能,就是支持在线数据不断优化模型。TensorFlow可以通过tf.train.Saver()来保存模型和恢复模型参数,使用Python加载模型文件后,可不断接受在线请求的数据,更新模型参数后通过Saver保存成checkpoint,用于下一次优化或者线上服务。 9 | 10 | 11 | 12 | #Session 13 | 神经网络 就是一个图片 14 | 15 | Session 是 Tensorflow 为了控制,和输出文件的执行的语句. 运行 session.run() 可以获得你要得知的运算结果, 或者是你所要运算的部分. 16 | 17 | session用来run() 我门设计好的结构,神经网络图片上的一个小结构,一个小功能,一个小图片,输出运行的结构的结果,如果指向一个参数的话就会输出当前参数值,如果指向一个运算的话就会输出运算的值 18 | 19 | 20 | #Tensor 21 | 22 | TensorFlow 程序使用 tensor 数据结构来代表所有的数据, 计算图中, 操作间传递的数据都是 tensor. 你可以把 TensorFlow tensor 看作是一个 n 维的数组或列表. 一个 tensor 包含一个静态类型 rank, 和 一个 shape. 23 | #变量 24 | Variables for more details. 变量维护图执行过程中的状态信息. 下面的例子演示了如何使用变量实现一个简单的计数器. 25 | 26 | 27 | #placeholder 28 | 也就是在sess.run()的时候再输入计算需要的值 29 | 30 | placeholder 是 Tensorflow 中的占位符,暂时储存变量.Tensorflow 如果想要从外部传入data, 那就需要用到 tf.placeholder(), 然后以这种形式传输数据 sess.run(***, feed_dict={input: **}). 31 | 32 | 需要传入的值放在了feed_dict={} 并一一对应每一个 input. placeholder 与 feed_dict={} 是绑定在一起出现的 33 | 34 | #激励函数 activation function 35 | 激励函数运行时激活神经网络中某一部分神经元,将激活信息向后传入下一层的神经系统。激励函数的实质是非线性方程。 Tensorflow 的神经网络 里面处理较为复杂的问题时都会需要运用激励函数 activation function 。 36 | 37 | ##分布式TensorFlow 38 | 分布式TensorFlow中ps、worker、in-graph、between-graph、synchronous training和asynchronous training的概念 39 | 40 | ps是整个训练集群的参数服务器,保存模型的Variable 41 | 42 | worker是计算模型梯度的节点,得到的梯度向量会交付给ps更新模型 43 | 44 | in-graph与between-graph对应,但两者都可以实现同步训练和异步训练,in-graph指整个集群由一个client来构建graph,并且由这个client来提交graph到集群中,其他worker只负责处理梯度计算的任务,而between-graph指的是一个集群中多个worker可以创建多个graph,但由于worker运行的代码相同因此构建的graph也相同,并且参数都保存到相同的ps中保证训练同一个模型,这样多个worker都可以构建graph和读取训练数据,适合大数据场景 45 | 46 | 同步训练和异步训练差异在于,同步训练每次更新梯度需要阻塞等待所有worker的结果,而异步训练不会有阻塞,训练的效率更高,在大数据和分布式的场景下一般使用异步训练。 47 | 48 | 49 | 在一幅 TensorFlow 图中,每个节点(node)有一个或者多个输入和零个或者多个输出,表示一种操作(operation)的实例化。 50 | 51 | ##TensorFlow Serving 52 | TensorFlow Serving 能够简化并加速从模型到生产的过程。它能实现在服务器架构和 API 保持不变的情况下,安全地部署新模型并运行试验。除了原生集成 TensorFlow,还可以扩展服务其他类型的模型。 53 | 54 | #语法 55 | ``` 56 | 创建一个一行两列的矩阵 57 | matrix1 = tf.constant([[3., 3.]]) 58 | 创建一个两行一列的矩阵 59 | matrix2 = tf.constant([[2.],[2.]]) 60 | 矩阵相乘 61 | tf.matmul(matrix1, matrix2) 62 | 启动默认图. 63 | sess = tf.Session() 64 | result = sess.run(product) 65 | 任务完成, 关闭会话. 66 | sess.close() 67 | 创建一个变量列表,(变量维护图的中间状态) 68 | tf.Variable([1.0, 2.0]) 69 | 创建一个常量列表 70 | tf.constant([3.0, 3.0]) 71 | 使用初始化器 initializer op 的 run() 方法初始化 'x' 72 | x.initializer.run() 73 | 增加一个减法 sub op, 从 'x' 减去 'a'. 运行减法 op, 输出结果 74 | sub = tf.sub(x, a) 75 | 计算state 和 one 的值 76 | new_value = tf.add(state, one) 77 | 将 new_value 的值 赋给 state (state=new_value) 78 | update = tf.assign(state, new_value) 79 | ``` 80 | 81 | 82 | ## 83 | 池化层 84 | 卷积层 85 | 86 | 过拟合 drop out 87 | 欠拟合 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /tensorflow_01.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import tensorflow as tf 3 | hello = tf.constant('Hello,TensorFlow!') 4 | sess = tf.Session() 5 | print(sess.run(hello)) 6 | a = tf.constant(10) 7 | b = tf.constant(32) 8 | print(sess.run(a + b)) 9 | saver_path = saver.save(sess, "/Users/yangyibo/Idea/python/AI/model.ckpt") -------------------------------------------------------------------------------- /tensorflow_02_case.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 预测一个线性的直线 ,预测 y = 0.1*x+0.3 3 | import tensorflow as tf 4 | # 导入科学计算模块 5 | import numpy as np 6 | 7 | #自己编一些数据,因为在tensorflow 中,他的大部分数据格式是 float 32 的形式 8 | x_data = np.random.rand(100).astype(np.float32) 9 | # 这就是我们预测的 y=Weights * x + biases Weights 接近0.1 激励 接近0.3 然后神经网络也就是学着把 Weights 变成 0.1, biases 变成 0.3 10 | y_data = x_data*0.1 + 0.3 11 | 12 | # 开始创建 tensorflow 的结构 13 | # Weights可能是个矩阵,此处定义 Weights 变量是一个一维的 参数范围为 -1.0 到 1.0的变量 14 | Weights = tf.Variable(tf.random_uniform([1], -1.0, 1.0)) 15 | # biases 是一个一维变量,初始值是 0 16 | biases = tf.Variable(tf.zeros([1])) 17 | # 上边两步是生成两个初始值,Weights 和 biases ,然后 Weights 和 biases 经过学习会越来越趋近于 0.1 和 0.3 18 | 19 | 20 | # 预测的y 21 | y = Weights*x_data + biases 22 | # 接着就是计算 y预测值 和 y_data真实值 的误差: 23 | loss = tf.reduce_mean(tf.square(y-y_data)) 24 | 25 | # 建立一个优化器, 减少神将网络的误差 GradientDescentOptimizer 是最基础的优化器, 0.5 为学习效率(0-1), 26 | optimizer = tf.train.GradientDescentOptimizer(0.5) 27 | train = optimizer.minimize(loss) 28 | 29 | # 初始化变量 ,神经网络就是一个图,上边就是建立结构,这里是初始化变量,激活图 30 | # init = tf.initialize_all_variables() # tf 马上就要废弃这种写法 31 | init = tf.global_variables_initializer() # 替换成这样就好 32 | 33 | 34 | sess = tf.Session() 35 | # 从init 开始 跑我们的图片,init 就是神经网络的入口 36 | sess.run(init) 37 | 38 | # 训练201次 39 | for step in range(201): 40 | # 开始训练 41 | sess.run(train) 42 | if step % 20 == 0: 43 | # 每隔20 次训练 输出一下当前我的 Weights参数 和 biases参数 , run(Weights) 就是像指针一样指向我图中的 Weights 44 | print(step, sess.run(Weights), sess.run(biases)) 45 | 46 | -------------------------------------------------------------------------------- /tensorflow_03_session.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 目标 学习session ,输出两个矩阵想乘的结果 3 | import tensorflow as tf 4 | 5 | # 一个一行两列的矩阵 6 | matrix1 = tf.constant([[3,3]]) 7 | # 一个两行一列的矩阵 8 | matrix2 = tf.constant([[2], 9 | [2]]) 10 | 11 | # 矩阵想乘 3*2 + 3*2 =12 类似 np 的 np.dot(m1,m2) 12 | product = tf.matmul(matrix1,matrix2) 13 | 14 | # method 1 15 | sess = tf.Session() 16 | # 执行 product 计算 结构 17 | result = sess.run(product) 18 | print(result) 19 | sess.close() 20 | 21 | # method 2 22 | # 打开 tf.Session() 以 sess 命名 不用管 sess.close() 在运行最后会自动关闭 23 | with tf.Session() as sess: 24 | 25 | result2 = sess.run(product) 26 | print(result2) 27 | print('abel') 28 | -------------------------------------------------------------------------------- /tensorflow_04_Variable.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 目标 Tensorflow 中使用 Variable 定义了某字符串是变量,它才是变量,这一点是与 Python 所不同的。 3 | # 定义语法: state = tf.Variable() 4 | import tensorflow as tf 5 | 6 | state = tf.Variable(0,name='counter') 7 | print(state.name) 8 | # 定义一个常量 9 | one = tf.constant(1) 10 | 11 | # 定义加法步骤 (注: 此步并没有直接计算) 12 | new_value = tf.add(state, one) 13 | 14 | # 更新 new_value 加载到了 state 也就是 state = new_value 15 | update = tf.assign( state, new_value) 16 | 17 | # 如果定义 Variable, 就一定要 initialize 激活变量 (此时没有激活只有 sess.run 才会激活) 18 | init = tf.global_variables_initializer() 19 | 20 | with tf.Session() as sess: 21 | sess.run(init) 22 | # 做3次循环 23 | for _ in range(3): 24 | sess.run(update); 25 | # print(state) 是无效的。一定要把 sess 的指针指向 state 再进行 print 才能得到想要的结果! 26 | print(sess.run(state)) -------------------------------------------------------------------------------- /tensorflow_05_placeholder.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 目标 Tensorflow 中的 placeholder , placeholder 是 Tensorflow 中的占位符,暂时储存变量. 3 | # Tensorflow 如果想要从外部传入data, 那就需要用到 tf.placeholder(), 然后以这种形式传输数据 sess.run(***, feed_dict={input: **}). 4 | import tensorflow as tf 5 | 6 | 7 | #在 Tensorflow 中需要定义 placeholder 的 type ,一般为 float32 形式 8 | # tf.placeholder(tf.float32,[2,2]) 规定数据结构 9 | input1 = tf.placeholder(tf.float32) 10 | input2 = tf.placeholder(tf.float32) 11 | 12 | # mul = multiply 是将input1和input2 做乘法运算,并输出为 output 13 | ouput = tf.multiply(input1, input2) 14 | 15 | with tf.Session() as sess: 16 | # 以feed_dict 传入参数,python 字典的格式 17 | # 需要传入的值放在了feed_dict={} 并一一对应每一个 input. placeholder 与 feed_dict={} 是绑定在一起出现的。 18 | print(sess.run(ouput,feed_dict={input1: [7.], input2: [2.]})) -------------------------------------------------------------------------------- /tensorflow_10_dropout.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 用 drop out 解决 Overfitting 问题 3 | import 手写数字识别.input_data 4 | import tensorflow as tf 5 | mnist = 手写数字识别.input_data.read_data_sets("手写数字识别/MNIST_data/", one_hot=True) 6 | 7 | # 添加神经层的函数def add_layer(),它有四个参数:输入值、输入的大小、输出的大小和激励函数,我们设定默认的激励函数是None。也就是线性函数 8 | def add_layer(inputs, in_size, out_size,layer_name, activation_function=None): 9 | # 定义权重,尽量是一个随机变量 10 | # 因为在生成初始参数时,随机变量(normal distribution) 会比全部为0要好很多,所以我们这里的weights 是一个 in_size行, out_size列的随机变量矩阵。 11 | Weights = tf.Variable(tf.random_normal([in_size, out_size])) 12 | # 在机器学习中,biases的推荐值不为0,所以我们这里是在0向量的基础上又加了0.1。 13 | biases = tf.Variable(tf.zeros([1, out_size]) + 0.1) 14 | # 定义Wx_plus_b, 即神经网络未激活的值(预测的值)。其中,tf.matmul()是矩阵的乘法。 15 | Wx_plus_b = tf.matmul(inputs, Weights) + biases 16 | # 用dropout来解决过拟合 问题 17 | Wx_plus_b = tf.nn.dropout(Wx_plus_b, keep_prob) 18 | # activation_function ——激励函数(激励函数是非线性方程)为None时(线性关系),输出就是当前的预测值——Wx_plus_b, 19 | # 不为None时,就把Wx_plus_b传到activation_function()函数中得到输出。 20 | if activation_function is None: 21 | outputs = Wx_plus_b 22 | else: 23 | # 返回输出 24 | outputs = activation_function(Wx_plus_b) 25 | tf.summary.histogram(layer_name + '/outputs', outputs) 26 | return outputs 27 | 28 | 29 | def compute_accuracy(v_xs,v_ys): 30 | # 定义 prediction 为全局变量 31 | global prediction 32 | # 将 xs data 在 prediction 中生成预测值,预测值也是一个 1*10 的矩阵 中每个值的概率,并不是一个0-9 的值,是0-9 每个值的概率 ,比如说3这个位置的概率最高,那么预测3就是这个图片的值 33 | y_pre = sess.run(prediction, feed_dict={xs: v_xs, keep_prob: 1}) 34 | # 对比我的预测值y_pre 和真实数据 v_ys 的差别 35 | correct_prediction = tf.equal(tf.argmax(y_pre,1), tf.argmax(v_ys,1)) 36 | # 计算我这一组数据中有多少个预测是对的,多少个是错的 37 | accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) 38 | # result 是一个百分比,百分比越高,预测越准确 39 | result = sess.run(accuracy, feed_dict={xs: v_xs, ys: v_ys,keep_prob: 1}) 40 | return result 41 | 42 | # 保留数据 keep_prob 43 | keep_prob = tf.placeholder(tf.float32) 44 | xs = tf.placeholder(tf.float32,[None, 784]) #图像输入向量 每个图片有784 (28 *28) 个像素点 45 | ys = tf.placeholder(tf.float32, [None,10]) #每个例子有10 个输出 46 | 47 | # prediction = add_layer(xs, 784, 10, activation_function=tf.nn.softmax) 48 | l1 = add_layer(xs, 784, 50, 'l1', activation_function=tf.nn.tanh) 49 | prediction = add_layer(l1, 50, 10,'l2' ,activation_function=tf.nn.softmax) 50 | #loss函数(即最优化目标函数)选用交叉熵函数。交叉熵用来衡量预测值和真实值的相似程度,如果完全相同,它们的交叉熵等于零 ,所以loss 越小 学的好 51 | #分类一般都是 softmax+ cross_entropy 52 | cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction), 53 | reduction_indices=[1])) 54 | tf.summary.scalar('loss', cross_entropy) 55 | 56 | #train方法(最优化算法)采用梯度下降法。 优化器 如何让机器学习提升它的准确率。 tf.train.GradientDescentOptimizer()中的值(学习的效率)通常都小于1 57 | train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy) 58 | sess = tf.Session() 59 | 60 | # tensorboard 必须一个 summary.histogram 和 一个 summary.scalar 61 | merged = tf.summary.merge_all() # tensorflow >= 0.12 62 | train_writer = tf.summary.FileWriter("/Users/yangyibo/test/logs/train",sess.graph) 63 | test_writer = tf.summary.FileWriter("/Users/yangyibo/test/logs/test",sess.graph) 64 | 65 | # 初始化变量 66 | init= tf.global_variables_initializer() 67 | sess.run(init) 68 | 69 | for i in range(3000): 70 | #开始train,每次只取100张图片,免得数据太多训练太慢 71 | batch_xs, batch_ys = mnist.train.next_batch(100) 72 | # 丢弃百分之10 的数据 73 | sess.run(train_step, feed_dict={xs: batch_xs, ys: batch_ys, keep_prob: 0.5}) 74 | if i % 50 == 0: 75 | # train_result test_result train_writer test_writer 用于将结果画在 tensorboard 上 76 | train_result = sess.run(merged, feed_dict={xs: batch_xs, ys: batch_ys, keep_prob: 1}) 77 | test_result = sess.run(merged, feed_dict={xs: mnist.test.images, ys: mnist.test.labels, keep_prob: 1}) 78 | train_writer.add_summary(train_result,i) 79 | test_writer.add_summary(test_result,i) 80 | # 输出结果 81 | print(compute_accuracy( 82 | mnist.test.images, mnist.test.labels)) 83 | -------------------------------------------------------------------------------- /tensorflow_11_CNN_卷积神经网络.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 手写数字识别 3 | # 准确度 0.9679 4 | import 手写数字识别.input_data 5 | import tensorflow as tf 6 | mnist = 手写数字识别.input_data.read_data_sets("手写数字识别/MNIST_data/", one_hot=True) 7 | 8 | def compute_accuracy(v_xs,v_ys): 9 | # 定义 prediction 为全局变量 10 | global prediction 11 | # 将 xs data 在 prediction 中生成预测值,预测值也是一个 1*10 的矩阵 中每个值的概率,并不是一个0-9 的值,是0-9 每个值的概率 ,比如说3这个位置的概率最高,那么预测3就是这个图片的值 12 | y_pre = sess.run(prediction, feed_dict={xs: v_xs,keep_prob: 1}) 13 | # 对比我的预测值y_pre 和真实数据 v_ys 的差别 14 | correct_prediction = tf.equal(tf.argmax(y_pre,1), tf.argmax(v_ys,1)) 15 | # 计算我这一组数据中有多少个预测是对的,多少个是错的 16 | accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) 17 | # result 是一个百分比,百分比越高,预测越准确 18 | result = sess.run(accuracy, feed_dict={xs: v_xs, ys: v_ys,keep_prob: 1}) 19 | return result 20 | 21 | #我们定义Weight变量,输入shape,返回变量的参数。其中我们使用tf.truncted_normal产生随机变量来进行初始化 22 | def weight_variable(shape): 23 | #google 也是用truncted_normal 来产生随机变量 24 | initial = tf.truncated_normal(shape,stddev=0.1) 25 | return tf.Variable(initial) 26 | #定义biase变量,输入shape ,返回变量的一些参数。其中我们使用tf.constant常量函数来进行初始化 27 | def bias_variable(shape): 28 | #定义成 0.1之后才会从0.1变到其他的值, bias通常用正直比较好,所以我们用0.1 29 | initial = tf.constant(0.1,shape=shape) 30 | return tf.Variable(initial) 31 | 32 | #定义卷积,tf.nn.conv2d函数是tensoflow里面的二维的卷积函数,x是图片的所有参数,W是此卷积层的权重 33 | def conv2d(x,W): 34 | #定义步长strides=[1,1,1,1]值,strides[0]和strides[3]的两个1是默认值,中间两个1代表padding时在x方向运动一步,y方向运动一步 35 | #padding采用的方式是SAME。 36 | return tf.nn.conv2d(x,W,strides=[1,1,1,1],padding='SAME') 37 | 38 | #定义池化pooling x 为conv2d 的返回 ,在pooling 阶段图片的长和宽被减小 39 | def max_poo_2x2(x): 40 | #步长strides=[1,2,2,1]值,strides[0]和strides[3]的两个1是默认值,中间两个2代表padding时在x方向运动两步,y方向运动两步 41 | return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME') 42 | 43 | xs = tf.placeholder(tf.float32,[None, 784]) #图像输入向量 每个图片有784 (28 *28) 个像素点 44 | ys = tf.placeholder(tf.float32, [None,10]) #每个例子有10 个输出 45 | keep_prob = tf.placeholder(tf.float32) 46 | 47 | 48 | 49 | # 处理输入图片的信息 把xs的形状变成[-1,28,28,1],-1代表先不考虑输入的图片例子多少这个维度,28 28 代表的是长和宽 后面的1是channel的数量,因为我们输入的图片是黑白的,因此channel是1,例如如果是RGB图像,那么channel就是3 50 | xs_image = tf.reshape(xs,[-1,28,28,1]) 51 | # print(xs_image.shape) 52 | 53 | # 第一层## 54 | # 定义本层的Weight,本层我们的卷积核patch的大小是5x5,因为黑白图片channel是1 是图片的厚度 所以输入是1 彩色的厚度是3,输出是32个featuremap 55 | W_conv1 = weight_variable([5,5,1,32]) 56 | # 大小是32个长度,因此我们传入它的shape为[32] 57 | b_conv1= bias_variable([32]) 58 | # 卷积神经网络的第一个卷积层, 对h_conv1进行非线性处理,也就是激活函数来处理 tf.nn.relu(修正线性单元)来处理,要注意的是,因为采用了SAME的padding方式, 59 | # 输出图片的大小没有变化依然是28x28,只是厚度变厚了,因此现在的输出大小就变成了28x28x32 60 | h_conv1 =tf.nn.relu(conv2d(xs_image,W_conv1) + b_conv1) 61 | # 经过pooling的处理,输出大小就变为了14x14x32 62 | h_pool1 = max_poo_2x2(h_conv1) 63 | 64 | # 第二层## 65 | # 定义本层的Weight,本层我们的卷积核patch的大小是5x5,32 是图片的厚度,输出是64个featuremap 66 | W_conv2 = weight_variable([5,5,32,64]) 67 | # 大小是64个长度,因此我们传入它的shape为[64] 68 | b_conv2= bias_variable([64]) 69 | # 卷积神经网络的第二个卷积层, 对h_conv2进行非线性处理,也就是激活函数来处理 tf.nn.relu(修正线性单元)来处理,要注意的是,因为采用了SAME的padding方式, 70 | # 输出图片的大小没有变化依然是14x14,只是厚度变厚了,因此现在的输出大小就变成了14x14x64 71 | h_conv2 =tf.nn.relu(conv2d(h_pool1,W_conv2) + b_conv2) 72 | # 经过pooling的处理,输出大小就变为了7x7x64 73 | h_pool2 = max_poo_2x2(h_conv2) 74 | 75 | 76 | #func1 layer## 77 | # 参考上面注释 78 | W_fc1 = weight_variable([7*7*64,1024]) 79 | b_fc1 = bias_variable([1024]) 80 | # 通过tf.reshape()将h_pool2的输出值从一个三维的变为一维的数据, -1表示先不考虑输入图片例子维度, 将上一个输出结果展平, 81 | h_pool2_flat = tf.reshape(h_pool2,[-1,7*7*64]) #[n_samples,7,7,64]->>[n_samples,7*7*64] 82 | 83 | # 将展平后的h_pool1_flat与本层的W_fc1相乘(注意这个时候不是卷积了) 84 | h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat,W_fc1)+b_fc1) 85 | # 考虑过拟合问题,可以加一个dropout的处理 86 | h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob) 87 | 88 | 89 | #func2 layer## 90 | W_fc2 = weight_variable([1024,10]) 91 | b_fc2 = bias_variable([10]) 92 | 93 | # 预测值,prediction 用softmax 处理 计算概率 94 | prediction = tf.nn.softmax(tf.matmul(h_fc1_drop,W_fc2)+b_fc2) 95 | 96 | 97 | #loss函数(即最优化目标函数)选用交叉熵函数。交叉熵用来衡量预测值和真实值的相似程度,如果完全相同,它们的交叉熵等于零 ,所以loss 越小 学的好 98 | #分类一般都是 softmax+ cross_entropy 99 | cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction), 100 | reduction_indices=[1])) 101 | # cross_entropy = -tf.reduce_sum(ys*tf.log(prediction)) 102 | 103 | #train方法(最优化算法)AdamOptimizer()作为我们的优化器进行优化 ,AdamOptimizer 适合比较庞大的系统 ,1e-4 0.0004 104 | train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy) 105 | sess = tf.Session() 106 | 107 | # 初始化变量 108 | init= tf.global_variables_initializer() 109 | sess.run(init) 110 | 111 | for i in range(1000): 112 | #开始train,每次只取100张图片,免得数据太多训练太慢 113 | batch_xs, batch_ys = mnist.train.next_batch(100) 114 | sess.run(train_step, feed_dict={xs: batch_xs, ys: batch_ys,keep_prob: 0.5}) 115 | if i % 50 == 0: 116 | print(compute_accuracy( 117 | mnist.test.images, mnist.test.labels)) -------------------------------------------------------------------------------- /tensorflow_12_save_神经网络.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # save 训练好的神经网络,以便下次使用 3 | # tensorflow 目前还不能保存 整个 神经网络框架只能保存我门的 Variable 4 | import tensorflow as tf 5 | import numpy as np 6 | 7 | 8 | # save Variable 9 | 10 | # 两行 三列 的 Weights,,最好定义一下 dtype 一般都是 tf.float32 name 又没有都可以 11 | # 记得定义 形状 和 dtype 在导入的时候 12 | # W = tf.Variable([[1,2,3],[3,4,5]], dtype=tf.float32, name='weights') 13 | 14 | # b = tf.Variable([[1,2,3]], dtype=tf.float32, name='biases') 15 | 16 | 17 | # init = tf.global_variables_initializer() 18 | 19 | # # 定义saver 20 | # saver = tf.train.Saver() 21 | 22 | # with tf.Session() as sess: 23 | # sess.run(init) 24 | # # 保存的是整个session 中的东西, 保存到my_net/save_net.ckpt ,官方默认后缀 ckpt 25 | # save_path = saver.save(sess,"my_net/save_net.ckpt") 26 | # print("save_path: ",save_path) 27 | 28 | 29 | 30 | # restore Variable 31 | # 重新定义和保存的 网络 相同 形状和类型的 网络才能正确导入 32 | 33 | 34 | # 形状是两行 三列的 的矩阵 dtype=tf.float32 35 | W = tf.Variable(np.arange(6).reshape((2, 3)), dtype=tf.float32, name="weights") 36 | # 形状是一行 三列的 的矩阵 dtype=tf.float32 37 | b = tf.Variable(np.arange(3).reshape((1,3)), dtype=tf.float32, name='biases') 38 | 39 | # 在restore 的时候不用 init 了 40 | saver = tf.train.Saver() 41 | 42 | with tf.Session() as sess: 43 | saver.restore(sess,"my_net/save_net.ckpt") 44 | print("weights: ",sess.run(W)) 45 | print("biases: ",sess.run(b)) 46 | 47 | -------------------------------------------------------------------------------- /tesorflow_06_add_layer.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 定义一个神经层 3 | import tensorflow as tf 4 | 5 | # 添加神经层的函数def add_layer(),它有四个参数:输入值、输入的大小、输出的大小和激励函数,我们设定默认的激励函数是None。也就是线性函数 6 | def add_layer(inputs, in_size, out_size, activation_function=None): 7 | # 定义权重,尽量是一个随机变量 8 | # 因为在生成初始参数时,随机变量(normal distribution) 会比全部为0要好很多,所以我们这里的weights 是一个 in_size行, out_size列的随机变量矩阵。 9 | Weights = tf.Variable(tf.random_normal([in_size,out_size])) 10 | # 在机器学习中,biases的推荐值不为0,所以我们这里是在0向量的基础上又加了0.1。 11 | biases = tf.Variable(tf.zores([1,out_size]) + 0.1) 12 | # 定义Wx_plus_b, 即神经网络未激活的值(预测的值)。其中,tf.matmul()是矩阵的乘法。 13 | Wx_plus_b = tf.matmul(inputs,Weights)+biases 14 | # activation_function ——激励函数(激励函数是非线性方程)为None时(线性关系),输出就是当前的预测值——Wx_plus_b, 15 | # 不为None时,就把Wx_plus_b传到activation_function()函数中得到输出。 16 | if activation_function = None: 17 | outputs = Wx_plus_b 18 | else: 19 | outputs=activation_function(Wx_plus_b) 20 | # 返回输出 21 | return outputs 22 | 23 | # 添加一个神经层的函数——def add_layer()就定义好了。 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /tesorflow_07_构建神经网络.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # -*- coding: utf-8 -*- 3 | # 定义一个神经层,主要用于学习 建立神经网络的结构,怎么运行,怎么优化 4 | import tensorflow as tf 5 | 6 | import numpy as np 7 | 8 | import matplotlib.pyplot as plt 9 | 10 | 11 | # 添加神经层的函数def add_layer(),它有四个参数:输入值、输入的大小、输出的大小和激励函数,我们设定默认的激励函数是None。也就是线性函数 12 | def add_layer(inputs, in_size, out_size, activation_function=None): 13 | # 定义权重,尽量是一个随机变量 14 | # 因为在生成初始参数时,随机变量(normal distribution) 会比全部为0要好很多,所以我们这里的weights 是一个 in_size行, out_size列的随机变量矩阵。 15 | Weights = tf.Variable(tf.random_normal([in_size, out_size])) 16 | # 在机器学习中,biases的推荐值不为0,所以我们这里是在0向量的基础上又加了0.1。 17 | biases = tf.Variable(tf.zeros([1, out_size]) + 0.1) 18 | # 定义Wx_plus_b, 即神经网络未激活的值(预测的值)。其中,tf.matmul()是矩阵的乘法。 19 | Wx_plus_b = tf.matmul(inputs, Weights) + biases 20 | # activation_function ——激励函数(激励函数是非线性方程)为None时(线性关系),输出就是当前的预测值——Wx_plus_b, 21 | # 不为None时,就把Wx_plus_b传到activation_function()函数中得到输出。 22 | if activation_function is None: 23 | outputs = Wx_plus_b 24 | else: 25 | # 返回输出 26 | outputs = activation_function(Wx_plus_b) 27 | return outputs 28 | 29 | # 添加一个神经层的函数——def add_layer()就定义好了。 30 | 31 | 32 | # 数据准备 33 | # -1到1这个区间,有300个单位,[:,np.newaxis] 加纬度,x_data 一个特性有300个例子 34 | x_data = np.linspace(-1,1,300,dtype=np.float32)[:,np.newaxis] 35 | 36 | # 噪点,使点分布在 线性方程的线的两边,使数据看起来更加真实 ,他的幂是0 方差是0.05,格式 是x_data 一样的格式 37 | noise = np.random.normal(0, 0.05, x_data.shape).astype(np.float32) 38 | 39 | # np.square(x_data) x_data 的二次方 40 | y_data = np.square(x_data) - 0.5 + noise 41 | 42 | # 典型神经网络,三层神经 43 | # 输入层 输入多少个data 输入层就有多少个神经元 44 | # 输入属性和输出属性都是 1 ,None 指给出多少个例子都可以 45 | xs = tf.placeholder(tf.float32, [None, 1]) 46 | ys = tf.placeholder(tf.float32, [None, 1]) 47 | 48 | # 隐藏层 假设十个神经元 49 | # 输入 x_data ,x_data的size=1 ,out_size=10 50 | l1 = add_layer(xs, 1, 10, activation_function=tf.nn.relu) 51 | 52 | # 输出层 有一个输出 所以一个神经元 53 | # 从隐藏层拿到数据 放入add_layer 执行。 数据是 l1 size =10 (因为 隐藏层的out_size=10) ,out_size=1 激励函数为空 54 | prediction = add_layer(l1, 10, 1, activation_function=None) 55 | 56 | #predition和真实值的偏差 将10个例子的每个例子的结果都减去predition取平方,然后再求和,然后取平均 57 | loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - prediction), 58 | reduction_indices=[1])) 59 | # 优化器 如何让机器学习提升它的准确率。 tf.train.GradientDescentOptimizer()中的值(学习的效率)通常都小于1,这里取的是0.1,代表以0.1的效率来最小化(minimize 减小)误差loss。 60 | # 每一个练习的步骤都通过这个优化器 以学习进度0.1的效率 对误差进行更正和提升,下一次就有更好的结果。 61 | train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss) 62 | 63 | 64 | # 初始化变量 65 | init= tf.global_variables_initializer() 66 | 67 | # 定义session 68 | sess = tf.Session() 69 | # 执行init 70 | sess.run(init) 71 | 72 | # 可视化,生成一个图片框 73 | fig = plt.figure() 74 | # add_subplot 画连续性的图 75 | ax = fig.add_subplot(1,1,1) 76 | # 添加真实的数据,以点的形式 打印出来 77 | ax.scatter(x_data, y_data) 78 | # show 后 函数不暂停,能够继续执行 79 | plt.ion() 80 | plt.show() 81 | 82 | 83 | # 训练1000步 84 | for i in range(1000): 85 | sess.run(train_step, feed_dict={xs: x_data, ys: y_data}) 86 | if i%50 == 0: 87 | # print(sess.run(loss,feed_dict={xs: x_data, ys: y_data} )) 88 | # 输出数据 89 | try: 90 | # 去除掉图片的lines 的 第一个线 91 | ax.lines.remove(lines[0]) 92 | except Exception: 93 | pass 94 | prediction_value=sess.run(prediction, feed_dict={xs: x_data}) 95 | # 将prediction 的值 plt 上去,以线的形势 96 | # x 轴为x_data Y 轴 为prediction_value 颜色为红色,宽度为5 97 | lines = ax.plot(x_data, prediction_value, 'r-', lw=5) 98 | 99 | # 暂停0.1S 100 | plt.pause(0.2) 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /tesorflow_08_可视化好棒手_tensorboard1.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # -*- coding: utf-8 -*- 3 | # 学会用 Tensorflow 自带的 tensorboard 去可视化我们所建造出来的神经网络是一个很好的学习理解方式. 用最直观的流程图告诉你你的神经网络是长怎样,有助于你发现编程中间的问题和疑问. 4 | # 定义一个神经层,用于图表展示 5 | # 定义名字需要在tf 的函数后面 加上 name 6 | import tensorflow as tf 7 | 8 | import numpy as np 9 | 10 | import matplotlib.pyplot as plt 11 | 12 | 13 | # 添加神经层的函数def add_layer(),它有四个参数:输入值、输入的大小、输出的大小和激励函数,我们设定默认的激励函数是None。也就是线性函数 14 | def add_layer(inputs, in_size, out_size, activation_function=None): 15 | with tf.name_scope('layer'): 16 | with tf.name_scope('Weights'): 17 | # 定义权重,尽量是一个随机变量 18 | # 因为在生成初始参数时,随机变量(normal distribution) 会比全部为0要好很多,所以我们这里的weights 是一个 in_size行, out_size列的随机变量矩阵。 19 | Weights = tf.Variable(tf.random_normal([in_size, out_size]),name='W') 20 | with tf.name_scope('biases'): 21 | # 在机器学习中,biases的推荐值不为0,所以我们这里是在0向量的基础上又加了0.1。 22 | biases = tf.Variable( 23 | tf.zeros([1, out_size]) + 0.1, 24 | name='b') 25 | with tf.name_scope('Wx_plus_b'): 26 | # 定义Wx_plus_b, 即神经网络未激活的值(预测的值)。其中,tf.matmul()是矩阵的乘法。 27 | Wx_plus_b = tf.add(tf.matmul(inputs, Weights),biases) 28 | # activation_function ——激励函数(激励函数是非线性方程)为None时(线性关系),输出就是当前的预测值——Wx_plus_b, 29 | # 不为None时,就把Wx_plus_b传到activation_function()函数中得到输出。 30 | if activation_function is None: 31 | outputs = Wx_plus_b 32 | else: 33 | # 返回输出 34 | outputs = activation_function(Wx_plus_b) 35 | return outputs 36 | 37 | # 添加一个神经层的函数——def add_layer()就定义好了。 38 | 39 | 40 | #定义一个大的框架,包含x_input和 y_input 41 | with tf.name_scope('inputs'): 42 | # 输入层 输入多少个data 输入层就有多少个神经元 43 | # 输入属性和输出属性都是 1 ,None 指给出多少个例子都可以 44 | xs = tf.placeholder(tf.float32, [None, 1],name='x_input') 45 | ys = tf.placeholder(tf.float32, [None, 1],name='y_input') 46 | 47 | # add hidden layer 隐藏层 假设十个神经元 48 | # 输入 x_data ,x_data的size=1 ,out_size=10 49 | l1 = add_layer(xs, 1, 10, activation_function=tf.nn.relu) 50 | 51 | # add output layer 输出层 有一个输出 所以一个神经元 52 | # 从隐藏层拿到数据 放入add_layer 执行。 数据是 l1 size =10 (因为 隐藏层的out_size=10) ,out_size=1 激励函数为空 53 | prediction = add_layer(l1, 10, 1, activation_function=None) 54 | 55 | with tf.name_scope('loss'): 56 | #predition和真实值的偏差 将10个例子的每个例子的结果都减去predition取平方,然后再求和,然后取平均 57 | loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - prediction), 58 | reduction_indices=[1])) 59 | 60 | with tf.name_scope('train_step'): 61 | # 优化器 如何让机器学习提升它的准确率。 tf.train.GradientDescentOptimizer()中的值(学习的效率)通常都小于1,这里取的是0.1,代表以0.1的效率来最小化(minimize 减小)误差loss。 62 | # 每一个练习的步骤都通过这个优化器 以学习进度0.1的效率 对误差进行更正和提升,下一次就有更好的结果。 63 | train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss) 64 | 65 | 66 | # 定义session 67 | sess = tf.Session() 68 | #把整个框架加载到一个文件中去 69 | writer = tf.summary.FileWriter("/Users/yangyibo/test/logs/",sess.graph) 70 | # 执行init 71 | sess.run(tf.initialize_all_variables()) 72 | 73 | 74 | # 在 /Users/yangyibo/test/ 目录下 执行 这个目录是我门框架加载到的那个文件的路径 75 | # tensorboard --logdir logs 76 | 77 | # 然后 chrome 浏览器打开 http://localhost:6006 78 | # 然后选择 graphs tab 就可以了。 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /tesorflow_09_可视化好棒手_tensorboard2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 学会用 Tensorflow 自带的 tensorboard 去可视化我们所建造出来的神经网络是一个很好的学习理解方式. 用最直观的流程图告诉你你的神经网络是长怎样,有助于你发现编程中间的问题和疑问. 3 | # 定义一个神经层,用于图表展示 使用 tensorboard 去展示神经网络学习的过程,从而用来优化神经网络 4 | import tensorflow as tf 5 | 6 | import numpy as np 7 | 8 | import matplotlib.pyplot as plt 9 | 10 | 11 | # 添加神经层的函数def add_layer(),它有四个参数:输入值、输入的大小、输出的大小和激励函数,我们设定默认的激励函数是None。也就是线性函数 12 | def add_layer(inputs, in_size, out_size, n_layer, activation_function=None): 13 | layer_name='layer%s'%n_layer ## define a new var 14 | with tf.name_scope('layer'): 15 | with tf.name_scope('Weights'): 16 | # 定义权重,尽量是一个随机变量 17 | # 因为在生成初始参数时,随机变量(normal distribution) 会比全部为0要好很多,所以我们这里的weights 是一个 in_size行, out_size列的随机变量矩阵。 18 | Weights = tf.Variable(tf.random_normal([in_size, out_size]),name='W') 19 | # tf.histogram_summary(layer_name+'/weights',Weights) # tensorflow 0.12 以下版的 20 | # 放在 histogram 里面则在 tensorboard 的 histogram 中展示 21 | tf.summary.histogram(layer_name + '/weights', Weights) # tensorflow >= 0.12 22 | with tf.name_scope('biases'): 23 | # 在机器学习中,biases的推荐值不为0,所以我们这里是在0向量的基础上又加了0.1。 24 | biases = tf.Variable( 25 | tf.zeros([1, out_size]) + 0.1, 26 | name='b') 27 | tf.summary.histogram(layer_name + '/biases', biases) 28 | with tf.name_scope('Wx_plus_b'): 29 | # 定义Wx_plus_b, 即神经网络未激活的值(预测的值)。其中,tf.matmul()是矩阵的乘法。 30 | Wx_plus_b = tf.add(tf.matmul(inputs, Weights),biases) 31 | # activation_function ——激励函数(激励函数是非线性方程)为None时(线性关系),输出就是当前的预测值——Wx_plus_b, 32 | # 不为None时,就把Wx_plus_b传到activation_function()函数中得到输出。 33 | if activation_function is None: 34 | outputs = Wx_plus_b 35 | else: 36 | # 返回输出 37 | outputs = activation_function(Wx_plus_b) 38 | tf.summary.histogram(layer_name + '/outputs', outputs) 39 | return outputs 40 | 41 | # 添加一个神经层的函数——def add_layer()就定义好了。 42 | 43 | 44 | # 数据准备 45 | # -1到1这个区间,有300个单位,[:,np.newaxis] 加纬度,x_data 一个特性有300个例子 46 | x_data = np.linspace(-1,1,300,dtype=np.float32)[:,np.newaxis] 47 | # 噪点,使点分布在 线性方程的线的两边,使数据看起来更加真实 ,他的幂是0 方差是0.05,格式 是x_data 一样的格式 48 | noise = np.random.normal(0, 0.05, x_data.shape).astype(np.float32) 49 | # np.square(x_data) x_data 的二次方 50 | y_data = np.square(x_data) - 0.5 + noise 51 | 52 | 53 | 54 | 55 | #定义一个大的框架,包含x_input和 y_input 56 | with tf.name_scope('inputs'): 57 | # 输入层 输入多少个data 输入层就有多少个神经元 58 | # 输入属性和输出属性都是 1 ,None 指给出多少个例子都可以 59 | xs = tf.placeholder(tf.float32, [None, 1],name='x_input') 60 | ys = tf.placeholder(tf.float32, [None, 1],name='y_input') 61 | 62 | 63 | 64 | # add hidden layer 隐藏层 假设十个神经元 65 | # 输入 x_data ,x_data的size=1 ,out_size=10 66 | l1 = add_layer(xs, 1, 10,n_layer=1,activation_function=tf.nn.relu) 67 | 68 | # add output layer 输出层 有一个输出 所以一个神经元 69 | # 从隐藏层拿到数据 放入add_layer 执行。 数据是 l1 size =10 (因为 隐藏层的out_size=10) ,out_size=1 激励函数为空 70 | prediction = add_layer(l1, 10, 1,n_layer=2, activation_function=None) 71 | 72 | with tf.name_scope('loss'): 73 | #predition和真实值的偏差 将10个例子的每个例子的结果都减去predition取平方,然后再求和,然后取平均 74 | loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - prediction), 75 | reduction_indices=[1])) 76 | #当loss 越来越小的时候,说明这个神经网络学到东西了,如果loss 稳定了,说明这个神经网络已经不学习了 77 | # tf.scalar_summary('loss',loss) # tensorflow < 0.12 78 | # 放在 scalar 里面则在 tensorboard 的scalars 中展示 79 | tf.summary.scalar('loss', loss) # tensorflow >= 0.12 80 | 81 | with tf.name_scope('train_step'): 82 | # 优化器 如何让机器学习提升它的准确率。 tf.train.GradientDescentOptimizer()中的值(学习的效率)通常都小于1,这里取的是0.1,代表以0.1的效率来最小化(minimize 减小)误差loss。 83 | # 每一个练习的步骤都通过这个优化器 以学习进度0.1的效率 对误差进行更正和提升,下一次就有更好的结果。 84 | train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss) 85 | 86 | 87 | # 定义session 88 | sess = tf.Session() 89 | 90 | #给所有训练图合并 91 | # merged = tf.merge_all_summaries() # tensorflow < 0.12 92 | merged = tf.summary.merge_all() # tensorflow >= 0.12 93 | 94 | #把整个框架加载到一个文件中去 95 | writer = tf.summary.FileWriter("/Users/yangyibo/test/logs/",sess.graph) 96 | # 执行init 97 | sess.run(tf.initialize_all_variables()) 98 | 99 | for i in range(1000): 100 | sess.run(train_step,feed_dict={xs: x_data, ys: y_data}) 101 | if i%50 == 0: 102 | result = sess.run(merged,feed_dict={xs: x_data, ys: y_data}) 103 | writer.add_summary(result,i) 104 | 105 | 106 | # 在 /Users/yangyibo/test/ 目录下 执行 这个目录是我门框架加载到的那个文件的路径 107 | # tensorboard --logdir logs 108 | 109 | # 然后 chrome 浏览器打开 http://localhost:6006 110 | # 然后选择 scalar 或 histogram tab 就可以了。 图像中颜色越深的区域值的个数越多,颜色越浅的地方值个数越少 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /手写数字识别/input_data.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | from __future__ import division 3 | from __future__ import print_function 4 | 5 | import gzip 6 | import os 7 | import tempfile 8 | 9 | import numpy 10 | from six.moves import urllib 11 | from six.moves import xrange # pylint: disable=redefined-builtin 12 | import tensorflow as tf 13 | from tensorflow.contrib.learn.python.learn.datasets.mnist import read_data_sets -------------------------------------------------------------------------------- /手写数字识别/my_mnist.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 手写数字识别 3 | # 准确度 0.8802 4 | import input_data 5 | import tensorflow as tf 6 | mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) 7 | 8 | # 添加神经层的函数def add_layer(),它有四个参数:输入值、输入的大小、输出的大小和激励函数,我们设定默认的激励函数是None。也就是线性函数 9 | def add_layer(inputs, in_size, out_size, activation_function=None): 10 | # 定义权重,尽量是一个随机变量 11 | # 因为在生成初始参数时,随机变量(normal distribution) 会比全部为0要好很多,所以我们这里的weights 是一个 in_size行, out_size列的随机变量矩阵。 12 | Weights = tf.Variable(tf.random_normal([in_size, out_size])) 13 | # 在机器学习中,biases的推荐值不为0,所以我们这里是在0向量的基础上又加了0.1。 14 | biases = tf.Variable(tf.zeros([1, out_size]) + 0.1) 15 | # 定义Wx_plus_b, 即神经网络未激活的值(预测的值)。其中,tf.matmul()是矩阵的乘法。 16 | Wx_plus_b = tf.matmul(inputs, Weights) + biases 17 | # activation_function ——激励函数(激励函数是非线性方程)为None时(线性关系),输出就是当前的预测值——Wx_plus_b, 18 | # 不为None时,就把Wx_plus_b传到activation_function()函数中得到输出。 19 | if activation_function is None: 20 | outputs = Wx_plus_b 21 | else: 22 | # 返回输出 23 | outputs = activation_function(Wx_plus_b) 24 | return outputs 25 | 26 | # 添加一个神经层的函数——def add_layer()就定义好了。 27 | 28 | 29 | def compute_accuracy(v_xs,v_ys): 30 | # 定义 prediction 为全局变量 31 | global prediction 32 | # 将 xs data 在 prediction 中生成预测值,预测值也是一个 1*10 的矩阵 中每个值的概率,并不是一个0-9 的值,是0-9 每个值的概率 ,比如说3这个位置的概率最高,那么预测3就是这个图片的值 33 | y_pre = sess.run(prediction, feed_dict={xs: v_xs}) 34 | # 对比我的预测值y_pre 和真实数据 v_ys 的差别 35 | correct_prediction = tf.equal(tf.argmax(y_pre,1), tf.argmax(v_ys,1)) 36 | # 计算我这一组数据中有多少个预测是对的,多少个是错的 37 | accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) 38 | # result 是一个百分比,百分比越高,预测越准确 39 | result = sess.run(accuracy, feed_dict={xs: v_xs, ys: v_ys}) 40 | return result 41 | 42 | xs = tf.placeholder(tf.float32,[None, 784]) #图像输入向量 每个图片有784 (28 *28) 个像素点 43 | ys = tf.placeholder(tf.float32, [None,10]) #每个例子有10 个输出 44 | 45 | prediction = add_layer(xs, 784, 10, activation_function=tf.nn.softmax) 46 | 47 | #loss函数(即最优化目标函数)选用交叉熵函数。交叉熵用来衡量预测值和真实值的相似程度,如果完全相同,它们的交叉熵等于零 ,所以loss 越小 学的好 48 | #分类一般都是 softmax+ cross_entropy 49 | cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction), 50 | reduction_indices=[1])) 51 | # cross_entropy = -tf.reduce_sum(ys*tf.log(prediction)) 52 | 53 | #train方法(最优化算法)采用梯度下降法。 优化器 如何让机器学习提升它的准确率。 tf.train.GradientDescentOptimizer()中的值(学习的效率)通常都小于1 54 | train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy) 55 | sess = tf.Session() 56 | 57 | # 初始化变量 58 | init= tf.global_variables_initializer() 59 | sess.run(init) 60 | 61 | for i in range(1000): 62 | #开始train,每次只取100张图片,免得数据太多训练太慢 63 | batch_xs, batch_ys = mnist.train.next_batch(50) 64 | sess.run(train_step, feed_dict={xs: batch_xs, ys: batch_ys}) 65 | if i % 50 == 0: 66 | print(compute_accuracy( 67 | mnist.test.images, mnist.test.labels)) -------------------------------------------------------------------------------- /手写数字识别/test_mnist.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # 手写数字识别 4 | # 准确度 0.9135 5 | import input_data 6 | import tensorflow as tf 7 | 8 | #MNIST数据输入 如果没有这个数据则从远端下载 9 | mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) 10 | 11 | x = tf.placeholder(tf.float32,[None, 784]) #图像输入向量 每个图片有784 (28 *28) 个像素点 12 | W = tf.Variable(tf.zeros([784,10])) #权重,初始化值为全零 13 | b = tf.Variable(tf.zeros([10])) #偏置,初始化值为全零 14 | 15 | #进行模型计算,y是预测,y_ 是实际 16 | y = tf.nn.softmax(tf.matmul(x,W) + b) 17 | 18 | y_ = tf.placeholder("float", [None,10]) #每个例子有10 个输出 19 | 20 | #计算交叉熵 21 | cross_entropy = -tf.reduce_sum(y_*tf.log(y)) 22 | #接下来使用BP算法来进行微调,以0.01的学习速率 23 | train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy) 24 | 25 | #上面设置好了模型,添加初始化创建变量的操作 26 | init = tf.initialize_all_variables() 27 | #启动创建的模型,并初始化变量 28 | sess = tf.Session() 29 | sess.run(init) 30 | #开始训练模型,循环训练1000次 31 | for i in range(1000): 32 | #随机抓取训练数据中的100个批处理数据点 33 | batch_xs, batch_ys = mnist.train.next_batch(50) 34 | sess.run(train_step, feed_dict={x:batch_xs,y_:batch_ys}) 35 | 36 | ''''' 进行模型评估 ''' 37 | 38 | #判断预测标签和实际标签是否匹配 39 | correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(y_,1)) 40 | accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) 41 | #计算所学习到的模型在测试数据集上面的正确率 42 | print( sess.run(accuracy, feed_dict={x:mnist.test.images, y_:mnist.test.labels}) ) -------------------------------------------------------------------------------- /猫狗识别/evaluateCatOrDog.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | import tensorflow as tf 3 | from PIL import Image 4 | import matplotlib.pyplot as plt 5 | import input_data 6 | import numpy as np 7 | import model 8 | import os 9 | 10 | #从训练集中选取一张图片 11 | def get_one_image(train): 12 | files = os.listdir(train) 13 | n = len(files) 14 | ind = np.random.randint(0,n) 15 | img_dir = os.path.join(train,files[ind]) 16 | image = Image.open(img_dir) 17 | plt.imshow(image) 18 | plt.show() 19 | image = image.resize([208, 208]) 20 | image = np.array(image) 21 | return image 22 | 23 | 24 | def evaluate_one_image(): 25 | train = '/Users/yangyibo/GitWork/pythonLean/AI/猫狗识别/testImg/' 26 | 27 | # 获取图片路径集和标签集 28 | image_array = get_one_image(train) 29 | 30 | with tf.Graph().as_default(): 31 | BATCH_SIZE = 1 # 因为只读取一副图片 所以batch 设置为1 32 | N_CLASSES = 2 # 2个输出神经元,[1,0] 或者 [0,1]猫和狗的概率 33 | # 转化图片格式 34 | image = tf.cast(image_array, tf.float32) 35 | # 图片标准化 36 | image = tf.image.per_image_standardization(image) 37 | # 图片原来是三维的 [208, 208, 3] 重新定义图片形状 改为一个4D 四维的 tensor 38 | image = tf.reshape(image, [1, 208, 208, 3]) 39 | logit = model.inference(image, BATCH_SIZE, N_CLASSES) 40 | # 因为 inference 的返回没有用激活函数,所以在这里对结果用softmax 激活 41 | logit = tf.nn.softmax(logit) 42 | 43 | # 用最原始的输入数据的方式向模型输入数据 placeholder 44 | x = tf.placeholder(tf.float32, shape=[208, 208, 3]) 45 | 46 | # 我门存放模型的路径 47 | logs_train_dir = '/Users/yangyibo/GitWork/pythonLean/AI/猫狗识别/saveNet/' 48 | # 定义saver 49 | saver = tf.train.Saver() 50 | 51 | with tf.Session() as sess: 52 | 53 | print("从指定的路径中加载模型。。。。") 54 | # 将模型加载到sess 中 55 | ckpt = tf.train.get_checkpoint_state(logs_train_dir) 56 | if ckpt and ckpt.model_checkpoint_path: 57 | global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1] 58 | saver.restore(sess, ckpt.model_checkpoint_path) 59 | print('模型加载成功, 训练的步数为 %s' % global_step) 60 | else: 61 | print('模型加载失败,,,文件没有找到') 62 | # 将图片输入到模型计算 63 | prediction = sess.run(logit, feed_dict={x: image_array}) 64 | # 获取输出结果中最大概率的索引 65 | max_index = np.argmax(prediction) 66 | if max_index==0: 67 | print('猫的概率 %.6f' %prediction[:, 0]) 68 | else: 69 | print('狗的概率 %.6f' %prediction[:, 1]) 70 | # 测试 71 | evaluate_one_image() 72 | -------------------------------------------------------------------------------- /猫狗识别/input_data.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | import os 3 | import numpy as np 4 | 5 | def get_files(file_dir): 6 | cats = [] 7 | label_cats = [] 8 | dogs = [] 9 | label_dogs = [] 10 | for file in os.listdir(file_dir): 11 | name = file.split(sep='.') 12 | if 'cat' in name[0]: 13 | cats.append(file_dir + file) 14 | label_cats.append(0) 15 | else: 16 | if 'dog' in name[0]: 17 | dogs.append(file_dir + file) 18 | label_dogs.append(1) 19 | image_list = np.hstack((cats,dogs)) 20 | label_list = np.hstack((label_cats,label_dogs)) 21 | # print('There are %d cats\nThere are %d dogs' %(len(cats), len(dogs))) 22 | # 多个种类分别的时候需要把多个种类放在一起,打乱顺序,这里不需要 23 | 24 | # 把标签和图片都放倒一个 temp 中 然后打乱顺序,然后取出来 25 | temp = np.array([image_list,label_list]) 26 | temp = temp.transpose() 27 | # 打乱顺序 28 | np.random.shuffle(temp) 29 | 30 | # 取出第一个元素作为 image 第二个元素作为 label 31 | image_list = list(temp[:,0]) 32 | label_list = list(temp[:,1]) 33 | label_list = [int(i) for i in label_list] 34 | return image_list,label_list 35 | 36 | # 测试 get_files 37 | # imgs , label = get_files('/Users/yangyibo/GitWork/pythonLean/AI/猫狗识别/testImg/') 38 | # for i in imgs: 39 | # print("img:",i) 40 | 41 | # for i in label: 42 | # print('label:',i) 43 | # 测试 get_files end 44 | 45 | 46 | # image_W ,image_H 指定图片大小,batch_size 每批读取的个数 ,capacity队列中 最多容纳元素的个数 47 | def get_batch(image,label,image_W,image_H,batch_size,capacity): 48 | # 转换数据为 ts 能识别的格式 49 | image = tf.cast(image,tf.string) 50 | label = tf.cast(label, tf.int32) 51 | 52 | # 将image 和 label 放倒队列里 53 | input_queue = tf.train.slice_input_producer([image,label]) 54 | label = input_queue[1] 55 | # 读取图片的全部信息 56 | image_contents = tf.read_file(input_queue[0]) 57 | # 把图片解码,channels =3 为彩色图片, r,g ,b 黑白图片为 1 ,也可以理解为图片的厚度 58 | image = tf.image.decode_jpeg(image_contents,channels =3) 59 | # 将图片以图片中心进行裁剪或者扩充为 指定的image_W,image_H 60 | image = tf.image.resize_image_with_crop_or_pad(image, image_W, image_H) 61 | # 对数据进行标准化,标准化,就是减去它的均值,除以他的方差 62 | image = tf.image.per_image_standardization(image) 63 | 64 | # 生成批次 num_threads 有多少个线程根据电脑配置设置 capacity 队列中 最多容纳图片的个数 tf.train.shuffle_batch 打乱顺序, 65 | image_batch, label_batch = tf.train.batch([image, label],batch_size = batch_size, num_threads = 64, capacity = capacity) 66 | 67 | # 重新定义下 label_batch 的形状 68 | label_batch = tf.reshape(label_batch , [batch_size]) 69 | # 转化图片 70 | image_batch = tf.cast(image_batch,tf.float32) 71 | return image_batch, label_batch 72 | 73 | 74 | # test get_batch 75 | # import matplotlib.pyplot as plt 76 | # BATCH_SIZE = 2 77 | # CAPACITY = 256 78 | # IMG_W = 208 79 | # IMG_H = 208 80 | 81 | # train_dir = '/Users/yangyibo/GitWork/pythonLean/AI/猫狗识别/testImg/' 82 | 83 | # image_list, label_list = get_files(train_dir) 84 | # image_batch, label_batch = get_batch(image_list, label_list, IMG_W, IMG_H, BATCH_SIZE, CAPACITY) 85 | 86 | # with tf.Session() as sess: 87 | # i = 0 88 | # # Coordinator 和 start_queue_runners 监控 queue 的状态,不停的入队出队 89 | # coord = tf.train.Coordinator() 90 | # threads = tf.train.start_queue_runners(coord=coord) 91 | # # coord.should_stop() 返回 true 时也就是 数据读完了应该调用 coord.request_stop() 92 | # try: 93 | # while not coord.should_stop() and i<1: 94 | # # 测试一个步 95 | # img, label = sess.run([image_batch, label_batch]) 96 | 97 | # for j in np.arange(BATCH_SIZE): 98 | # print('label: %d' %label[j]) 99 | # # 因为是个4D 的数据所以第一个为 索引 其他的为冒号就行了 100 | # plt.imshow(img[j,:,:,:]) 101 | # plt.show() 102 | # i+=1 103 | # # 队列中没有数据 104 | # except tf.errors.OutOfRangeError: 105 | # print('done!') 106 | # finally: 107 | # coord.request_stop() 108 | # coord.join(threads) 109 | # sess.close() 110 | 111 | 112 | -------------------------------------------------------------------------------- /猫狗识别/model.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | import tensorflow as tf 3 | # 结构 4 | # conv1 卷积层 1 5 | # pooling1_lrn 池化层 1 6 | # conv2 卷积层 2 7 | # pooling2_lrn 池化层 2 8 | # local3 全连接层 1 9 | # local4 全连接层 2 10 | # softmax 全连接层 3 11 | def inference(images, batch_size, n_classes): 12 | 13 | with tf.variable_scope('conv1') as scope: 14 | # 卷积盒的为 3*3 的卷积盒,图片厚度是3,输出是16个featuremap 15 | weights = tf.get_variable('weights', 16 | shape=[3, 3, 3, 16], 17 | dtype=tf.float32, 18 | initializer=tf.truncated_normal_initializer(stddev=0.1, dtype=tf.float32)) 19 | biases = tf.get_variable('biases', 20 | shape=[16], 21 | dtype=tf.float32, 22 | initializer=tf.constant_initializer(0.1)) 23 | conv = tf.nn.conv2d(images, weights, strides=[1, 1, 1, 1], padding='SAME') 24 | pre_activation = tf.nn.bias_add(conv, biases) 25 | conv1 = tf.nn.relu(pre_activation, name=scope.name) 26 | 27 | with tf.variable_scope('pooling1_lrn') as scope: 28 | pool1 = tf.nn.max_pool(conv1, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='SAME', name='pooling1') 29 | norm1 = tf.nn.lrn(pool1, depth_radius=4, bias=1.0, alpha=0.001 / 9.0, beta=0.75, name='norm1') 30 | 31 | with tf.variable_scope('conv2') as scope: 32 | weights = tf.get_variable('weights', 33 | shape=[3, 3, 16, 16], 34 | dtype=tf.float32, 35 | initializer=tf.truncated_normal_initializer(stddev=0.1, dtype=tf.float32)) 36 | biases = tf.get_variable('biases', 37 | shape=[16], 38 | dtype=tf.float32, 39 | initializer=tf.constant_initializer(0.1)) 40 | conv = tf.nn.conv2d(norm1, weights, strides=[1, 1, 1, 1], padding='SAME') 41 | pre_activation = tf.nn.bias_add(conv, biases) 42 | conv2 = tf.nn.relu(pre_activation, name='conv2') 43 | 44 | # pool2 and norm2 45 | with tf.variable_scope('pooling2_lrn') as scope: 46 | norm2 = tf.nn.lrn(conv2, depth_radius=4, bias=1.0, alpha=0.001 / 9.0, beta=0.75, name='norm2') 47 | pool2 = tf.nn.max_pool(norm2, ksize=[1, 3, 3, 1], strides=[1, 1, 1, 1], padding='SAME', name='pooling2') 48 | 49 | with tf.variable_scope('local3') as scope: 50 | reshape = tf.reshape(pool2, shape=[batch_size, -1]) 51 | dim = reshape.get_shape()[1].value 52 | weights = tf.get_variable('weights', 53 | shape=[dim, 128], 54 | dtype=tf.float32, 55 | initializer=tf.truncated_normal_initializer(stddev=0.005, dtype=tf.float32)) 56 | biases = tf.get_variable('biases', 57 | shape=[128], 58 | dtype=tf.float32, 59 | initializer=tf.constant_initializer(0.1)) 60 | local3 = tf.nn.relu(tf.matmul(reshape, weights) + biases, name=scope.name) 61 | 62 | # local4 63 | with tf.variable_scope('local4') as scope: 64 | weights = tf.get_variable('weights', 65 | shape=[128, 128], 66 | dtype=tf.float32, 67 | initializer=tf.truncated_normal_initializer(stddev=0.005, dtype=tf.float32)) 68 | biases = tf.get_variable('biases', 69 | shape=[128], 70 | dtype=tf.float32, 71 | initializer=tf.constant_initializer(0.1)) 72 | local4 = tf.nn.relu(tf.matmul(local3, weights) + biases, name='local4') 73 | 74 | # softmax 75 | with tf.variable_scope('softmax_linear') as scope: 76 | weights = tf.get_variable('softmax_linear', 77 | shape=[128, n_classes], 78 | dtype=tf.float32, 79 | initializer=tf.truncated_normal_initializer(stddev=0.005, dtype=tf.float32)) 80 | biases = tf.get_variable('biases', 81 | shape=[n_classes], 82 | dtype=tf.float32, 83 | initializer=tf.constant_initializer(0.1)) 84 | softmax_linear = tf.add(tf.matmul(local4, weights), biases, name='softmax_linear') 85 | 86 | return softmax_linear 87 | 88 | 89 | 90 | def losses(logits, labels): 91 | with tf.variable_scope('loss') as scope: 92 | cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits \ 93 | (logits=logits, labels=labels, name='xentropy_per_example') 94 | loss = tf.reduce_mean(cross_entropy, name='loss') 95 | tf.summary.scalar(scope.name + '/loss', loss) 96 | return loss 97 | 98 | def trainning(loss, learning_rate): 99 | with tf.name_scope('optimizer'): 100 | optimizer = tf.train.AdamOptimizer(learning_rate= learning_rate) 101 | global_step = tf.Variable(0, name='global_step', trainable=False) 102 | train_op = optimizer.minimize(loss, global_step= global_step) 103 | return train_op 104 | 105 | def evaluation(logits, labels): 106 | with tf.variable_scope('accuracy') as scope: 107 | correct = tf.nn.in_top_k(logits, labels, 1) 108 | correct = tf.cast(correct, tf.float16) 109 | accuracy = tf.reduce_mean(correct) 110 | tf.summary.scalar(scope.name + '/accuracy', accuracy) 111 | return accuracy -------------------------------------------------------------------------------- /猫狗识别/training.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import tensorflow as tf 4 | import input_data 5 | import model 6 | 7 | 8 | N_CLASSES = 2 # 2个输出神经元,[1,0] 或者 [0,1]猫和狗的概率 9 | IMG_W = 208 # 重新定义图片的大小,图片如果过大则训练比较慢 10 | IMG_H = 208 11 | BATCH_SIZE = 32 #每批数据的大小 12 | CAPACITY = 256 13 | MAX_STEP = 15000 # 训练的步数,应当 >= 10000 14 | learning_rate = 0.0001 # 学习率,建议刚开始的 learning_rate <= 0.0001 15 | 16 | 17 | def run_training(): 18 | 19 | # 数据集 20 | train_dir = '/Users/yangyibo/GitWork/pythonLean/AI/猫狗识别/img/' #My dir--20170727-csq 21 | #logs_train_dir 存放训练模型的过程的数据,在tensorboard 中查看 22 | logs_train_dir = '/Users/yangyibo/GitWork/pythonLean/AI/猫狗识别/saveNet/' 23 | 24 | # 获取图片和标签集 25 | train, train_label = input_data.get_files(train_dir) 26 | # 生成批次 27 | train_batch, train_label_batch = input_data.get_batch(train, 28 | train_label, 29 | IMG_W, 30 | IMG_H, 31 | BATCH_SIZE, 32 | CAPACITY) 33 | # 进入模型 34 | train_logits = model.inference(train_batch, BATCH_SIZE, N_CLASSES) 35 | # 获取 loss 36 | train_loss = model.losses(train_logits, train_label_batch) 37 | # 训练 38 | train_op = model.trainning(train_loss, learning_rate) 39 | # 获取准确率 40 | train__acc = model.evaluation(train_logits, train_label_batch) 41 | # 合并 summary 42 | summary_op = tf.summary.merge_all() 43 | sess = tf.Session() 44 | # 保存summary 45 | train_writer = tf.summary.FileWriter(logs_train_dir, sess.graph) 46 | saver = tf.train.Saver() 47 | 48 | sess.run(tf.global_variables_initializer()) 49 | coord = tf.train.Coordinator() 50 | threads = tf.train.start_queue_runners(sess=sess, coord=coord) 51 | 52 | try: 53 | for step in np.arange(MAX_STEP): 54 | if coord.should_stop(): 55 | break 56 | _, tra_loss, tra_acc = sess.run([train_op, train_loss, train__acc]) 57 | 58 | if step % 50 == 0: 59 | print('Step %d, train loss = %.2f, train accuracy = %.2f%%' %(step, tra_loss, tra_acc*100.0)) 60 | summary_str = sess.run(summary_op) 61 | train_writer.add_summary(summary_str, step) 62 | 63 | if step % 2000 == 0 or (step + 1) == MAX_STEP: 64 | # 每隔2000步保存一下模型,模型保存在 checkpoint_path 中 65 | checkpoint_path = os.path.join(logs_train_dir, 'model.ckpt') 66 | saver.save(sess, checkpoint_path, global_step=step) 67 | 68 | except tf.errors.OutOfRangeError: 69 | print('Done training -- epoch limit reached') 70 | finally: 71 | coord.request_stop() 72 | coord.join(threads) 73 | sess.close() 74 | 75 | # train 76 | run_training() 77 | -------------------------------------------------------------------------------- /验证码识别/CodeDemo.py: -------------------------------------------------------------------------------- 1 | 2 | import matplotlib.pyplot as plt 3 | from PIL import Image 4 | 5 | def get_bin_table(threshold=140): 6 | """ 7 | 获取灰度转二值的映射table 8 | :param threshold: 9 | :return: 10 | """ 11 | table = [] 12 | for i in range(256): 13 | if i < threshold: 14 | table.append(0) 15 | else: 16 | table.append(1) 17 | 18 | return table 19 | 20 | 21 | image = Image.open('img/0UnZ.jpg') 22 | 23 | imgry = image.convert('L')# 转化为灰度图 24 | table = get_bin_table() 25 | out = imgry.point(table, '1') 26 | print(out) 27 | 28 | f = plt.figure() 29 | plt.imshow(out) 30 | plt.show() 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /验证码识别/getImg.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding:utf8 -*- 3 | 4 | import os 5 | 6 | # 方法一 7 | def file_name(file_dir): 8 | for root, dirs, files in os.walk(file_dir): 9 | # print(root) #当前目录路径 10 | # print(dirs) #当前路径下所有子目录 11 | print(files) #当前路径下所有非目录子文件 12 | 13 | # 方法二 14 | def gci(filepath): 15 | #遍历filepath下所有文件,包括子目录 16 | files = os.listdir(filepath) 17 | for fi in files: 18 | fi_d = os.path.join(filepath,fi) 19 | if os.path.isdir(fi_d): 20 | gci(fi_d) 21 | else: 22 | print(os.path.join(filepath,fi_d)) 23 | 24 | 25 | # gci('/Users/yangyibo/GitWork/pythonLean/AI/验证码识别/img/') 26 | # file_name('/Users/yangyibo/GitWork/pythonLean/AI/验证码识别/img/') 27 | 28 | def getlabel(len,str): 29 | number = [] 30 | for item in range(0,len,1): 31 | number.append(int(str[item:item+1])) 32 | print(number) 33 | # item = item+1 34 | 35 | 36 | 37 | 38 | number ='1024' 39 | 40 | 41 | getlabel(len(number),number) 42 | 43 | 44 | numlist=[int( number[item: item+1] ) for item in range(0, len(number), 1)] 45 | print(numlist) 46 | 47 | -------------------------------------------------------------------------------- /验证码识别/input_data.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | import os 3 | import numpy as np 4 | 5 | # size 6 | img_width = 60 7 | img_height = 20 8 | 9 | def oneHotlabel(len,str): 10 | labels = [] 11 | for item in range(0,len,1): 12 | labels.append(int(str[item:item+1])) 13 | return tf.one_hot(labels,10,on_value=1,off_value=None) 14 | 15 | def get_files(file_dir): 16 | images = [] 17 | labels = [] 18 | for file in os.listdir(file_dir): 19 | name = file.split(sep='.') 20 | labels.append(oneHotlabel(4,name[0])) 21 | images.append(file_dir+file) 22 | 23 | # 多个种类分别的时候需要把多个种类放在一起,打乱顺序,这里不需要 24 | # image_list = np.hstack(cat_images,dog_images) 25 | # label_list = np.hstack(cat_labels,dog_labels) 26 | 27 | # 把标签和图片都放倒一个 temp 中 然后打乱顺序,然后取出来 28 | temp = np.array([images,labels]) 29 | temp = temp.transpose() 30 | # 打乱顺序 31 | np.random.shuffle(temp) 32 | 33 | # 取出第一个元素作为 image 第二个元素作为 label 34 | image_list = list(temp[:,0]) 35 | label_list = list(temp[:,1]) 36 | return image_list,label_list 37 | 38 | # 测试 get_files 39 | # imgs , label = get_files('/Users/yangyibo/GitWork/pythonLean/AI/验证码识别/img/') 40 | # for i in imgs: 41 | # print(i) 42 | 43 | 44 | # with tf.Session() as sess: 45 | # for i in label: 46 | # print('label:',sess.run(i)) 47 | # 测试 get_files end 48 | 49 | 50 | # image_W ,image_H 指定图片大小,batch_size 每批读取的个数 ,capacity队列中 最多容纳元素的个数 51 | def get_batch(image,label,image_W,image_H,batch_size,capacity): 52 | # 转换数据为 ts 能识别的格式 53 | image = tf.cast(image,tf.string) 54 | label = tf.cast(label,tf.string) 55 | 56 | # 将image 和 label 放倒队列里 57 | input_queue = tf.train.slice_input_producer([image,label]) 58 | label = input_queue[1] 59 | # 读取图片的全部信息 60 | image_contents = tf.read_file(input_queue[0]) 61 | # 把图片解码,channels =3 为彩色图片, r,g ,b 黑白图片为 1 ,也可以理解为图片的厚度 62 | image = tf.image.decode_jpeg(image_contents,channels =3) 63 | # 将图片以图片中心进行裁剪或者扩充为 指定的image_W,image_H 64 | image = tf.image.resize_image_with_crop_or_pad(image, image_W, image_H) 65 | # 对数据进行标准化,标准化,就是减去它的均值,除以他的方差 66 | # image = tf.image.per_image_standardization(image) 67 | # 生成批次 num_threads 有多少个线程根据电脑配置设置 capacity 队列中 最多容纳图片的个数 tf.train.shuffle_batch 打乱顺序, 68 | image_batch, label_batch = tf.train.batch([image, label],batch_size = batch_size, num_threads = 64, capacity = capacity) 69 | # 重新定义下 label_batch 的形状 70 | # label_batch = tf.reshape(label_batch , [batch_size]) 71 | # 转化图片 72 | label_batch = tf.cast(label_batch,tf.float32) 73 | image_batch = tf.cast(image_batch,tf.float32) 74 | return image_batch, label_batch 75 | 76 | 77 | # test get_batch 78 | # import matplotlib.pyplot as plt 79 | # BATCH_SIZE = 2 80 | # CAPACITY = 256 81 | # IMG_W = 60 82 | # IMG_H = 40 83 | 84 | # train_dir = '/Users/yangyibo/GitWork/pythonLean/AI/验证码识别/img/' 85 | 86 | # image_list, label_list = get_files(train_dir) 87 | # image_batch, label_batch = get_batch(image_list, label_list, IMG_W, IMG_H, BATCH_SIZE, CAPACITY) 88 | 89 | # with tf.Session() as sess: 90 | # i = 0 91 | # # Coordinator 和 start_queue_runners 监控 queue 的状态,不停的入队出队 92 | # coord = tf.train.Coordinator() 93 | # threads = tf.train.start_queue_runners(coord=coord) 94 | # # coord.should_stop() 返回 true 时也就是 数据读完了应该调用 coord.request_stop() 95 | # try: 96 | # while not coord.should_stop() and i<1: 97 | # # 测试一个步 98 | # img, label = sess.run([image_batch, label_batch]) 99 | 100 | # for j in np.arange(BATCH_SIZE): 101 | # print(label[j]) 102 | # # print(type(label[j])) 103 | # # 因为是个4D 的数据所以第一个为 索引 其他的为冒号就行了 104 | # plt.imshow(img[j,:,:,:]) 105 | # plt.show() 106 | # i+=1 107 | # # 队列中没有数据 108 | # except tf.errors.OutOfRangeError: 109 | # print('done!') 110 | # finally: 111 | # coord.request_stop() 112 | # coord.join(threads) 113 | # sess.close() 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /验证码识别/model.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | import input_data 3 | 4 | #我们定义Weight变量,输入shape,返回变量的参数。其中我们使用tf.truncted_normal产生随机变量来进行初始化 5 | def weight_variable(shape): 6 | #google 也是用truncted_normal 来产生随机变量 7 | initial = tf.truncated_normal(shape,stddev=0.1) 8 | return tf.Variable(initial) 9 | #定义biase变量,输入shape ,返回变量的一些参数。其中我们使用tf.constant常量函数来进行初始化 10 | def bias_variable(shape): 11 | #定义成 0.1之后才会从0.1变到其他的值, bias通常用正直比较好,所以我们用0.1 12 | initial = tf.constant(0.1,shape=shape) 13 | return tf.Variable(initial) 14 | 15 | #定义卷积,tf.nn.conv2d函数是tensoflow里面的二维的卷积函数,x是图片的所有参数,W是此卷积层的权重 16 | def conv2d(x,W): 17 | #定义步长strides=[1,1,1,1]值,strides[0]和strides[3]的两个1是默认值,中间两个1代表padding时在x方向运动一步,y方向运动一步 18 | #padding采用的方式是SAME。 19 | return tf.nn.conv2d(x,W,strides=[1,1,1,1],padding='SAME') 20 | 21 | #定义池化pooling x 为conv2d 的返回 ,在pooling 阶段图片的长和宽被减小 22 | def max_poo_2x2(x): 23 | #步长strides=[1,2,2,1]值,strides[0]和strides[3]的两个1是默认值,中间两个2代表padding时在x方向运动两步,y方向运动两步 24 | return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME') 25 | 26 | xs = tf.placeholder(tf.float32,[None, 9600]) #图像输入向量 每个图片有784 (28 *28) 个像素点 27 | ys = tf.placeholder(tf.float32, [None,40]) #每个例子有10 个输出 28 | keep_prob = tf.placeholder(tf.float32) 29 | 30 | 31 | 32 | # 处理输入图片的信息 把xs的形状变成[-1,28,28,1],-1代表先不考虑输入的图片例子多少这个维度,28 28 代表的是长和宽 后面的1是channel的数量,因为我们输入的图片是黑白的,因此channel是1,例如如果是RGB图像,那么channel就是3 33 | xs_image = tf.reshape(xs,[-1,160,60,1]) 34 | # print(xs_image.shape) 35 | 36 | # 第一层## 37 | # 定义本层的Weight,本层我们的卷积核patch的大小是5x5,因为黑白图片channel是1 是图片的厚度 所以输入是1 彩色的厚度是3,输出是32个featuremap 38 | W_conv1 = weight_variable([5,5,1,32]) 39 | # 大小是32个长度,因此我们传入它的shape为[32] 40 | b_conv1= bias_variable([32]) 41 | # 卷积神经网络的第一个卷积层, 对h_conv1进行非线性处理,也就是激活函数来处理 tf.nn.relu(修正线性单元)来处理,要注意的是,因为采用了SAME的padding方式, 42 | # 输出图片的大小没有变化依然是28x28,只是厚度变厚了,因此现在的输出大小就变成了28x28x32 43 | h_conv1 =tf.nn.relu(conv2d(xs_image,W_conv1) + b_conv1) 44 | # 经过pooling的处理,输出大小就变为了14x14x32 45 | h_pool1 = max_poo_2x2(h_conv1) 46 | 47 | # 第二层## 48 | # 定义本层的Weight,本层我们的卷积核patch的大小是5x5,32 是图片的厚度,输出是64个featuremap 49 | W_conv2 = weight_variable([5,5,32,64]) 50 | # 大小是64个长度,因此我们传入它的shape为[64] 51 | b_conv2= bias_variable([64]) 52 | # 卷积神经网络的第二个卷积层, 对h_conv2进行非线性处理,也就是激活函数来处理 tf.nn.relu(修正线性单元)来处理,要注意的是,因为采用了SAME的padding方式, 53 | # 输出图片的大小没有变化依然是14x14,只是厚度变厚了,因此现在的输出大小就变成了14x14x64 54 | h_conv2 =tf.nn.relu(conv2d(h_pool1,W_conv2) + b_conv2) 55 | # 经过pooling的处理,输出大小就变为了7x7x64 56 | h_pool2 = max_poo_2x2(h_conv2) 57 | 58 | 59 | #func1 layer## 60 | # 参考上面注释 61 | W_fc1 = weight_variable([7*7*64,1024]) 62 | b_fc1 = bias_variable([1024]) 63 | # 通过tf.reshape()将h_pool2的输出值从一个三维的变为一维的数据, -1表示先不考虑输入图片例子维度, 将上一个输出结果展平, 64 | h_pool2_flat = tf.reshape(h_pool2,[-1,7*7*64]) #[n_samples,7,7,64]->>[n_samples,7*7*64] 65 | 66 | # 将展平后的h_pool1_flat与本层的W_fc1相乘(注意这个时候不是卷积了) 67 | h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat,W_fc1)+b_fc1) 68 | # 考虑过拟合问题,可以加一个dropout的处理 69 | h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob) 70 | 71 | 72 | #func2 layer## 73 | W_fc2 = weight_variable([1024,40]) 74 | b_fc2 = bias_variable([40]) 75 | 76 | # 预测值,prediction 用softmax 处理 计算概率 77 | prediction = tf.nn.softmax(tf.matmul(h_fc1_drop,W_fc2)+b_fc2) 78 | 79 | 80 | #loss函数(即最优化目标函数)选用交叉熵函数。交叉熵用来衡量预测值和真实值的相似程度,如果完全相同,它们的交叉熵等于零 ,所以loss 越小 学的好 81 | #分类一般都是 softmax+ cross_entropy 82 | cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction), 83 | reduction_indices=[1])) 84 | # cross_entropy = -tf.reduce_sum(ys*tf.log(prediction)) 85 | 86 | #train方法(最优化算法)AdamOptimizer()作为我们的优化器进行优化 ,AdamOptimizer 适合比较庞大的系统 ,1e-4 0.0004 87 | train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy) 88 | 89 | sess = tf.Session() 90 | 91 | # 初始化变量 92 | init= tf.global_variables_initializer() 93 | sess.run(init) 94 | 95 | for i in range(1000): 96 | #开始train,每次只取100张图片,免得数据太多训练太慢 97 | train, train_label = input_data.get_files('/Users/yangyibo/GitWork/pythonLean/AI/验证码识别/img/') 98 | batch_xs, batch_ys = input_data.get_batch(train,train_label,160, 60, 100,256) 99 | sess.run(train_step, feed_dict={xs: batch_xs, ys: batch_ys,keep_prob: 0.5}) 100 | # if i % 50 == 0: 101 | # print(compute_accuracy( 102 | # mnist.test.images, mnist.test.labels)) 103 | 104 | 105 | -------------------------------------------------------------------------------- /验证码识别/验证码生成器.py: -------------------------------------------------------------------------------- 1 | from captcha.image import ImageCaptcha # pip install captcha 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | from PIL import Image 5 | import random 6 | 7 | # 验证码中的字符, 就不用汉字了 8 | number = ['0','1','2','3','4','5','6','7','8','9'] 9 | # alphabet = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'] 10 | # ALPHABET = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'] 11 | # 验证码一般都无视大小写;验证码长度4个字符 12 | # def random_captcha_text(char_set=number+alphabet+ALPHABET, captcha_size=4): 13 | def random_captcha_text(char_set=number, captcha_size=4): 14 | captcha_text = [] 15 | for i in range(captcha_size): 16 | c = random.choice(char_set) 17 | captcha_text.append(c) 18 | return captcha_text 19 | 20 | # 生成字符对应的验证码 21 | def gen_captcha_text_and_image(): 22 | image = ImageCaptcha() 23 | 24 | captcha_text = random_captcha_text() 25 | captcha_text = ''.join(captcha_text) 26 | 27 | captcha = image.generate(captcha_text) 28 | #image.write(captcha_text, captcha_text + '.jpg') # 写到文件 29 | 30 | captcha_image = Image.open(captcha) 31 | captcha_image = np.array(captcha_image) 32 | return captcha_text, captcha_image 33 | 34 | # 生成并保存一张验证码图片 35 | def saveImage(): 36 | image = ImageCaptcha() 37 | 38 | captcha_text = random_captcha_text() 39 | captcha_text = ''.join(captcha_text) 40 | 41 | captcha = image.generate(captcha_text) 42 | image.write(captcha_text, 'img/'+captcha_text + '.jpg') # 写到文件 43 | 44 | # 展示验证码图片 45 | def showImage(): 46 | text, image = gen_captcha_text_and_image() 47 | f = plt.figure() 48 | ax = f.add_subplot(111) 49 | ax.text(0.1, 0.9,text, ha='center', va='center', transform=ax.transAxes) 50 | plt.imshow(image) 51 | plt.show() 52 | 53 | 54 | if __name__ == '__main__': 55 | # 测试 show image 56 | # showImage() 57 | for m in range(100) : 58 | saveImage() 59 | 60 | --------------------------------------------------------------------------------