用自己的数据在tensorflow中用逻辑回归分类iris鸢尾花种类

    xiaoxiao2022-07-02  116

    目录

    导入数据建立模型启动会话

    导入数据

    网上有很多的关于鸢尾花分类的博客都是从sklearn中直接导入的,因为上课的需要,需要用自己的数据来导入。我的数据是放在txt文件中的,首先看看大概的数据: 这里的前4列是花的特征,且我的数据只有100行,且只有两种花(最后一列独热编码只有0,1),当然3种花的做法和两种花的做法是一样的。后面用softmax来进行分类时会用到150行的数据,且有3种花。 导入数据的代码:

    def log_re(path,*batch): # 从文件夹中读取数据 data = np.loadtxt(path, dtype='float32', delimiter=None) # 总的数据的80%用于训练,其余的用于测试 length = int(len(data)*0.8) # 注意这里的x_trian,y_train都是二阶的,特别注意y_train x_train = [] y_train = [] # 当输入的batch的参数个数为1个时,表示会随机的输出batch个数据 if len(batch)> 0 and len(batch) < 2: # 随机的得到0到length之间的batch[0]个数,这里的batch[0]就是你输出的那个数 ran = random.sample(range(0,length),batch[0]) for i in ran: x = [] y = [] for j in range(len(data[0]) - 1): x.append(data[i][j]) if data[i][-1] == 0: y.append(1) y.append(0) if data[i][-1] == 1: y.append(0) y.append(1) # y.append(data[i][-1]) x_train.append(x) y_train.append(y) return x_train,y_train # 假如batch个数等于0,表示没有输入,即随机输出length个数 elif len(batch) == 0: batch1=length ran = random.sample(range(0, length), batch1) for i in ran: x = [] y = [] for j in range(len(data[0]) - 1): x.append(data[i][j]) if data[i][-1] == 0: y.append(1) y.append(0) if data[i][-1] == 1: y.append(0) y.append(1) # y.append(data[i][-1]) x_train.append(x) y_train.append(y) return x_train,y_train else: print("参数错误,请从新输出两个参数") return x_train,y_train

    这里得到的数据是总的数据的80%,这是用于训练的,并且每次输出都是随机的一个batch,batch的大小就是这个函数的第二个参数,这里默认的是batch=80,所以x_train和y_train的shape是(80,4)和(80,2)。 这里是直接把y_train变成了独热编码: 这里建议从在导入自己txt数据时用np.loadtxt(),个人觉得很好用。

    建立模型

    首先是定义参数和占位符: input_n = 4 #输入维度是4 output_n = 2 #输出维度是2 learn_rate = 0.5 #学习率 epoch = 20 #迭代次数,个人实验之后发现15次迭代之后就会有比较好的效果

    x1 = tf.placeholder(tf.float32,shape=[None,input_n]) y = tf.placeholder(tf.float32,shape=[None,output_n]) w1 = tf.Variable(tf.ones([input_n,output_n]),name='weight1') b1 = tf.Variable(tf.zeros([output_n]),name='base1') #下面的两句代码的功能相同 y_pre = tf.matmul(x1,w1) + b1 #y_pre = tf.nn.bias_add(tf.matmul(x1,w1),b1) #这里仅仅使用sigmoid函数和交叉熵来求解,没有用到softmax。 loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=y, logits=y_pre, name='loss') #这里用tf.reduce_mean()函数,表示的是平均的损失值 cross_entropy = tf.reduce_mean(loss) train_step = tf.train.GradientDescentOptimizer(learn_rate).minimize(cross_entropy) #tfarg_max()函数得到的是一行中最大的数的下标,tf.equal()函数是比较两个矩阵或向量是不是相同的,如果相同就是True #不是就是False, correct_prediction = tf.equal(tf.arg_max(y_pre, 1), tf.arg_max(y, 1)) #tf.cast()函数是转化类型的,这里就是转化为tf.float32类型,因为这里转化之后的值不是1就是0,所以用tf.reduce_mean() #函数之后得到的就是正确率 accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

    启动会话

    with tf.Session() as sess: init = tf.global_variables_initializer() sess.run(init) for i in range(epoch): x,y_ = log_re(path) sess.run(train_step,feed_dict={x1:x , y:y_}) cross_entr,acc = sess.run([cross_entropy,accuracy],feed_dict={x1:x,y:y_}) y_pred,corr = sess.run([y_pre,correct_prediction],feed_dict={x1:x,y:y_}) print("第%d次迭代,cross_entropy=%f" % (i,cross_entr)) print("第%d次迭代,acc=%f" % (i,acc)) # 通过验证大概在迭代15次左右就能达到很好的效果,甚至是100%的效果,所以还以存在过拟合的 # 当输出的值是一个向量或者矩阵时,建议用format来输出,这样可以整个输出矩阵或向量的值 print("第{}次迭代,correct_pre={}" .format(i,corr)) print("第{}次迭代,correct_pre={}" .format(i,y_pred))

    第一次迭代的结果: 从第一次迭代结果可以看出正确率比较小的,从correct_pre中就可以看出,里面的True和False有很多 第15次迭代结果: 从15次迭代看出,correct_pre全部都为True,猜想可能是出现过拟合,当然从另一方面看正确率确实是变高了。

    最新回复(0)