(四)tensorflow--猫狗分类

猫狗数据集介绍

对kaggle中的猫狗数据集使用Alexnet网络进行训练,该数据集包括25000张训练图片,12500张测试图片,包括猫和狗两种图片。

代码整体介绍

1.alexnet.py:定义alexnet网络
2.datagenerator.py: 对数据集做预处理,定义输入的方式
3.validate_image.py:对图像进行测试
4.main.py:主函数,在训练集上训练
alexnet.py

import tensorflow as tf
def alexnet(x,keep_prob,num_classes):
    #conv1
    with tf.name_scope('conv1') as scope:
        kernel = tf.Variable(tf.truncated_normal([11,11,3,96],dtype=tf.float32,stddev=1e-1),name='weights')
        conv = tf.nn.conv2d(x,kernel,[1,4,4,1],padding='SAME')
        biases = tf.Variable(tf.constant(0.0,shape=[96],dtype=tf.float32),trainable=True,name='biases')
        bias = tf.nn.bias_add(conv,biases)
        conv1 = tf.nn.relu(bias,name=scope)
    #lr1
    with tf.name_scope('lrn1') as scope:
        lrn1 = tf.nn.local_response_normalization(conv1,alpha=1e-4,beta=0.75,depth_radius=2,bias=2.0)
    #pool1
    with tf.name_scope('pool1') as scope:
        pool1 = tf.nn.max_pool(lrn1,ksize=[1,3,3,1],strides=[1,2,2,1],padding='VALID')
    #conv2
    with tf.name_scope('conv2') as scope:
        pool1_groups = tf.split(axis=3,value=pool1,num_or_size_splits=2)
        kernel = tf.Variable(tf.truncated_normal([5,5,48,256],dtype=tf.float32,stddev=1e-1),name='weights')
        kernel_groups = tf.split(axis=3,value=kernel,num_or_size_splits=2)
        conv_up = tf.nn.conv2d(pool1_groups[0],kernel_groups[0],[1,1,1,1],padding='SAME')
        conv_down = tf.nn.conv2d(pool1_groups[1],kernel_groups[1],[1,1,1,1],padding='SAME')
        biases = tf.Variable(tf.constant(0.0,shape=[256],dtype=tf.float32),trainable=True,name='biases')
        biases_groups = tf.split(axis=0,value=biases,num_or_size_splits=2)
        bias_up = tf.nn.bias_add(conv_up,biases_groups[0])
        bias_down = tf.nn.bias_add(conv_down,biases_groups[1])
        bias = tf.concat(axis=3,values=[bias_up,bias_down])
        conv2 = tf.nn.relu(bias,name=scope)
    #lrn2
    with tf.name_scope('lrn2') as scope:
        lrn2 = tf.nn.local_response_normalization(conv2,alpha=1e-4,beta=0.75,depth_radius=2,bias=2.0)
    #pool2
    with tf.name_scope('pool2') as scope:
        pool2 = tf.nn.max_pool(lrn2,ksize=[1,3,3,1],strides=[1,2,2,1],padding='VALID')
    #conv3
    with tf.name_scope('conv3') as scope:
        kernel = tf.Variable(tf.truncated_normal([3,3,256,384],dtype=tf.float32,stddev=1e-1),name='weights')
        conv = tf.nn.conv2d(pool2,kernel,[1,1,1,1],padding='SAME')
        biases = tf.Variable(tf.constant(0.0,shape=[384],dtype=tf.float32),trainable=True,name='biases')
        bias = tf.nn.bias_add(conv,biases)
        conv3 = tf.nn.relu(bias,name=scope)
    
    with tf.name_scope("conv4") as scope:
        conv3_groups = tf.split(axis=3,value=conv3,num_or_size_splits=2)
        kernel = tf.Variable(tf.truncated_normal([3,3,192,384],dtype=tf.float32,stddev=1e-1),name='weights')
        kernel_groups = tf.split(axis=3,value=kernel,num_or_size_splits=2)
        conv_up = tf.nn.conv2d(conv3_groups[0],kernel_groups[0],[1,1,1,1],padding="SAME")
        conv_down = tf.nn.conv2d(conv3_groups[1],kernel_groups[1],[1,1,1,1],padding="SAME")
        biases = tf.Variable(tf.constant(0.0,shape=[384],dtype=tf.float32),trainable=True,name='biases')
        biases_groups = tf.split(axis=0,value=biases,num_or_size_splits=2)
        bias_up = tf.nn.bias_add(conv_up,biases_groups[0])
        bias_down = tf.nn.bias_add(conv_down,biases_groups[1])
        bias = tf.concat(axis=3,values=[bias_up,bias_down])
        conv4 = tf.nn.relu(bias,name=scope)

    with tf.name_scope("conv5") as scope:
        conv4_groups = tf.split(axis=3,value=conv4,num_or_size_splits=2)
        kernel = tf.Variable(tf.truncated_normal([3,3,192,256],dtype=tf.float32,stddev=1e-1),name='weights')
        kernel_groups = tf.split(axis=3,value=kernel,num_or_size_splits=2)
        conv_up = tf.nn.conv2d(conv4_groups[0],kernel_groups[0],[1,1,1,1],padding='SAME')
        conv_down = tf.nn.conv2d(conv4_groups[1],kernel_groups[1],[1,1,1,1],padding='SAME')
        biases = tf.Variable(tf.constant(0.0,shape=[256],dtype=tf.float32),trainable=True,name='biases')
        biases_groups = tf.split(axis=0,value=biases,num_or_size_splits=2)
        bias_up = tf.nn.bias_add(conv_up,biases_groups[0])
        bias_down = tf.nn.bias_add(conv_down,biases_groups[1])
        bias  = tf.concat(axis=3,values=[bias_up,bias_down])
        conv5 = tf.nn.relu(bias,name=scope)

    with tf.name_scope("pool5") as scope:
        pool5 = tf.nn.max_pool(conv5,ksize=[1,3,3,1],strides=[1,2,2,1],padding='VALID')
    with tf.name_scope("flattened6") as scope:
        flattened = tf.reshape(pool5,shape=[-1,6*6*256])
    with tf.name_scope("fc6") as scope:
        weights = tf.Variable(tf.truncated_normal([6*6*256,4096],dtype=tf.float32,stddev=1e-1),name='weights')
        biases = tf.Variable(tf.constant(0.0,shape=[4096],dtype=tf.float32),trainable=True,name='biases')
        bias = tf.nn.xw_plus_b(flattened,weights,biases)
        fc6 = tf.nn.relu(bias)

    with tf.name_scope("dropout6") as scope:
        dropout6 = tf.nn.dropout(fc6,keep_prob)
    
    with tf.name_scope("fc7") as scope:
        weights = tf.Variable(tf.truncated_normal([4096,4096],dtype=tf.float32,stddev=1e-1),name='weights')
        biases = tf.Variable(tf.constant(0.0,shape=[4096],dtype=tf.float32),trainable=True,name='biases')
        bias = tf.nn.xw_plus_b(dropout6,weights,biases)
        fc7 = tf.nn.relu(bias)
    with tf.name_scope("dropout7") as scope:
        dropout7 = tf.nn.dropout(fc7,keep_prob)

    with tf.name_scope("fc8") as scope:
        weights = tf.Variable(tf.truncated_normal([4096,num_classes],dtype=tf.float32,stddev=1e-1),name='weights')
        biases = tf.Variable(tf.constant(0.0,shape=[num_classes],dtype=tf.float32),trainable=True,name='biases')
        fc8 = tf.nn.xw_plus_b(dropout7,weights,biases)
        
    return fc8

datagenerator.py

import numpy as np
import tensorflow as tf
from tensorflow.python.framework import dtypes
from tensorflow.python.framework.ops import convert_to_tensor
from tensorflow.data import Dataset
VGG_MEAN = tf.constant([123.68,116.779,103.939],dtype=tf.float32)
#图片数据转换为三维数据
class ImageDataGenerator(object):
    def __init__(self,images,labels,batch_size,num_classes,image_format='jpg',shuffle=True):
        self.img_paths = images
        self.labels = labels
        self.data_size = len(self.labels)
        self.num_classes = num_classes
        self.image_format = image_format
        if shuffle:
            self._shuffle_lists()

        self.img_paths = convert_to_tensor(self.img_paths,dtype=dtypes.string)
        self.labels = convert_to_tensor(self.labels,dtype=dtypes.int32)
        data = tf.data.Dataset.from_tensor_slices((self.img_paths,self.labels))
        data = data.map(self._parse_function_train)
        data = data.batch(batch_size)
        self.data = data

    def _shuffle_lists(self):
        path = self.img_paths
        labels = self.labels
        permutation = np.random.permutation(self.data_size)
        self.img_paths = []
        self.labels = []
        for i in permutation:
            self.img_paths.append(path[i])
            self.labels.append(labels[i])
    def _parse_function_train(self,filename,label):
        one_hot = tf.one_hot(label,self.num_classes)
        img_string = tf.read_file(filename)
        if self.image_format == "jpg":
            img_decoded = tf.image.decode_jpeg(img_string,channels=3)
        elif self.image_format == "png":
            img_decoded = tf.image.decode_png(img_string,channels=3)
        else:
            print("Error")
        img_resized = tf.image.resize_images(img_decoded,[227,227])
        img_centered  = tf.subtract(img_resized,VGG_MEAN)
        img_bgr = img_centered[:,:,::-1]
        return img_bgr,one_hot

main.py

import numpy as np
from VGG16_model import vgg16
import os
import tensorflow as tf
from alexnet import alexnet
from datagenerator import ImageDataGenerator
from datetime import datetime
import glob
from tensorflow.data import Iterator
def main():
    #超参数
    learning_rate = 1e-3
    num_epochs = 1
    train_batch_size = 8
    dropout_rate = 0.5
    num_classes = 2
    #format_size = [120,120]
    display_step = 20
    filewriter_path = './tsboard/'
    checkpoint_path = './checkpoints/'
    file_name_of_class = ['cat','dog']
    image_format = "jpg"
    train_dataset_paths="/home/dataset/kaggle/train/"
    #训练数据预处理
    train_image_paths = []
    train_labels = []
    train_image_paths = np.array(glob.glob(train_dataset_paths+'*.'+image_format)).tolist()
    print("train_image_length:",len(train_image_paths))
    for image_path in train_image_paths:
        image_file_name = image_path.split('/')[-1]
        for i in range(num_classes):
            if file_name_of_class[i] in image_file_name:
                train_labels.append(i)
                break
    #调用生成器
    train_data = ImageDataGenerator(
        images = train_image_paths,
        labels = train_labels,
        batch_size = train_batch_size,
        num_classes = num_classes,
        image_format = image_format,
        shuffle = True)
    #定义迭代器
    print(train_data.data.output_types,train_data.data.output_shapes)
    with tf.name_scope("input"):
        train_iterator = Iterator.from_structure(train_data.data.output_types,train_data.data.output_shapes)
        training_initalizer = train_iterator.make_initializer(train_data.data)
        train_next_batch =  train_iterator.get_next()
    x = tf.placeholder(tf.float32,[None,227,227,3]) 
    y = tf.placeholder(tf.float32,[None,num_classes])
    keep_prob = tf.placeholder(tf.float32)
    #定义alexnet网络
    logits = alexnet(x,keep_prob,num_classes)
    #定义vgg网络
    #x = tf.image.resize_images(x,format_size)
    #logits = vgg16(x,num_classes,isTrain=True,keep_prob=0.6)
    with tf.name_scope("loss"):
        loss_op = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=logits,labels=y))
    with tf.name_scope('optimizer'):
        optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
        train_op = optimizer.minimize(loss_op)
    train_prediction = tf.nn.softmax(logits)
    init = tf.global_variables_initializer()
    '''
    #tensorboard
    tf.summary.scalar('loss',loss_op)
    merged_summary = tf.summary.merge_all()
    writer = tf.summary.FileWriter(filewriter_path)
    '''
    saver = tf.train.Saver()
    train_batches_per_epoch = int(np.floor(train_data.data_size/train_batch_size))
    print(train_data.data_size)
    print(train_batches_per_epoch)
    with tf.Session() as sess:
        sess.run(init)
        #writer.add_graph(sess.graph)
        print("{}: start training...".format(datetime.now()))
        print("{}: openning tensorboard at --logdir{}".format(datetime.now(),filewriter_path))
        for epoch in range(num_epochs):
            sess.run(training_initalizer)
            print("{}:epoch number:{} start".format(datetime.now(),epoch+1))
            for step in range(500):
                img_batch,label_batch = sess.run(train_next_batch)
                loss,_,predictions = sess.run([loss_op,train_op,train_prediction],feed_dict={x:img_batch,y:label_batch,keep_prob:dropout_rate})
                if step % display_step == 0:
                    print("{}:loss={}".format(datetime.now(),loss))
                    print("accuracy = {}".format(accuracy(predictions,label_batch)))
                    #s = sess.run(merged_summary,feed_dict={x:img_batch,y:label_batch,keep_prob:1.})
                    #writer.add_summary(s,epoch*train_batches_per_epoch+step)
            #save model
            print("{}:saving checkpoint of model...".format(datetime.now()))
            checkpoint_name = os.path.join(checkpoint_path,'model_epoch' + str(epoch+1)+'.ckpt')
            save_path = saver.save(sess,checkpoint_name)
            print("{}:epoch number:{} end".format(datetime.now(),epoch+1))
def accuracy(predictions,labels):
    return 100.0*np.sum(np.argmax(predictions,1)==np.argmax(labels,1))/predictions.shape[0]
    

if __name__ == "__main__":

    main()

validate_image.py

import tensorflow as tf
from VGG16_model import vgg16
from alexnet import alexnet
import matplotlib.pyplot as plt
class_name = ['cat','dog']
def test_image(path_image,num_class):
    img_string = tf.read_file(path_image)
    img_decoded = tf.image.decode_png(img_string,channels=3)
    img_resized = tf.image.resize_images(img_decoded,[120,120])
    img_resized = tf.reshape(img_resized,shape=[1,120,120,3])
    fc8 = alexnet(img_resized,1,2)
    #vgg = vgg16(img_resized,num_class,return_all=True)
    #score = tf.nn.softmax(vgg[-3])
        score = tf.nn.softmax(fc8)
    print("score:",score)
    max = tf.argmax(score,1)
    saver = tf.train.Saver()
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        saver.restore(sess,'./checkpoints/model_epoch1.ckpt')
        #print(sess.run(vgg))
        #print("score",sess.run(score))
        prob = sess.run(max)[0]
        plt.imshow(img_decoded.eval())
        plt.title("class:"+class_name[prob])
        plt.show()
if __name__ == "__main__":
    test_image("/home/dataset/kaggle/test1/3572.jpg",num_class=2)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容