分类任务笔记

分类任务笔记

这是一个分类任务
net.py 是网络定义
dataset.py 是数据集接口定义
train.py 是训练文件,run_train.sh是脚本
inference.py 是测试文件,run_inference.sh是脚本

0.说明

1.sys.argv[]

从程序外部获取参数的桥梁

# test.py
import sys
a = sys.argv[0]
print(a)

>>> python test.py what
test.py
# 将给为sys.argv[1]
>>> python test.py what
what

2.tf.convert_to_tensor()

用于将不同数据变成张量:比如可以让数组变成张量、也可以让列表变成张量

<class 'tensorflow.python.framework.ops.Tensor'>

3.tf.argmax()

tf.argmax(input,axis)根据axis取值的不同返回每行或者每列最大值的索引

4. tf.equal()

tf.equal(x, y, name=None) 就是判断,x, y 是不是相等

如果相等就是True,不相等,就是False

5.tf.cast()

数据类型转换

1.dataset.py 数据集接口定义

'''ImageData 类
输入
@ txtfile        文本文件  
@ batch_size     批量迭代大小 64
@ num_classes    分类类别   2
@ image_size     图像大小(48*48)

输出
@ img
@ label
'''

__init__
'''初始化
对图像进行一些预处理 
image_size
batch_size
txt_file
num_classes
buffer_size   # 应用于 shuffle
'''
buffer_size = batch_size * buffer_scale  # 64*100



read_txt_file
	img_paths  # 图片路径
    labels     # 图片标签
import tensorflow as tf
from tensorflow.python.framework import dtypes
from tensorflow.python.framework.ops import convert_to_tensor
import numpy as np

class ImageData:
    def read_txt_file(self):
        self.img_paths = []      # 图片路径
        self.labels = []         # 标签
        for line in open(self.txt_file, 'r'):
            items = line.split(' ')
            self.img_paths.append(items[0])
            self.labels.append(int(items[1]))

    def __init__(self, txt_file, batch_size, num_classes,
                 image_size,buffer_scale=100):
        self.image_size = image_size
        self.batch_size = batch_size
        self.txt_file = txt_file ##txt list file,stored as: imagename id
        self.num_classes = num_classes
        buffer_size = batch_size * buffer_scale

        # 读取图片
        self.read_txt_file()
        self.dataset_size = len(self.labels)             # 训练集的数量
        print ("num of train datas=",self.dataset_size)    
        # 转换成Tensor
        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 = tf.data.Dataset.from_tensor_slices((self.img_paths, self.labels))
        print ("data type=",type(data))
        data = data.map(self.parse_function)
        data = data.repeat(1000)
        data = data.shuffle(buffer_size=buffer_size)

        # 设置self data Batch
        self.data = data.batch(batch_size)
        print ("self.data type=",type(self.data))
    
    def augment_dataset(self, image, size):
        distorted_image = tf.image.random_brightness(image,                 # 在某范围随机调整图片亮度 
                                                     max_delta=63)    
        distorted_image = tf.image.random_contrast(distorted_image,         # 在某范围随机调整图片对比度 
                                             lower=0.2, upper=1.8)
        # Subtract off the mean and divide by the variance of the pixels.
        float_image = tf.image.per_image_standardization(distorted_image)   # 归一化
        return float_image
    
    def parse_function(self, filename, label):
        label_ = tf.one_hot(label, self.num_classes)   # 标签编码
        img = tf.read_file(filename)                   # 读取
        img = tf.image.decode_jpeg(img, channels=3)    # 图像解码
        img = tf.image.convert_image_dtype(img, dtype = tf.float32)    # 改变图像数据类型
        img = tf.random_crop(img,[self.image_size[0],self.image_size[1],3])  # 随机剪裁
        img = tf.image.random_flip_left_right(img)                           # 随机翻转
        img = self.augment_dataset(img,self.image_size)                      
        return img, label_

2.net.py

x size = (?,48,48,3)
relu_conv1 size = (?, 23,23,12)
relu_conv2 size = (?, 11,11,24)
relu_conv3 size = (?, 5,5,48)
dense size = (?, 128)
'''
输入
@ x 输入数据
@ istraining 是否为训练
'''
import tensorflow as tf


def simpleconv3(x,istraining):
    x_shape = tf.shape(x)
    with tf.name_scope("simpleconv3"):
        with tf.variable_scope("conv3_net"):
            conv1 = tf.layers.conv2d(x, name="conv1", filters=12,kernel_size=[3,3], strides=(2,2), activation=tf.nn.relu,kernel_initializer=tf.contrib.layers.xavier_initializer(),bias_initializer=tf.contrib.layers.xavier_initializer())
            bn1 = tf.layers.batch_normalization(conv1, training=istraining, name='bn1')
            conv2 = tf.layers.conv2d(bn1, name="conv2", filters=24,kernel_size=[3,3], strides=(2,2), activation=tf.nn.relu,kernel_initializer=tf.contrib.layers.xavier_initializer(),bias_initializer=tf.contrib.layers.xavier_initializer())
            bn2 = tf.layers.batch_normalization(conv2, training=istraining, name='bn2')
            conv3 = tf.layers.conv2d(bn2, name="conv3", filters=48,kernel_size=[3,3], strides=(2,2), activation=tf.nn.relu,kernel_initializer=tf.contrib.layers.xavier_initializer(),bias_initializer=tf.contrib.layers.xavier_initializer())
            bn3 = tf.layers.batch_normalization(conv3, training=istraining, name='bn3')
            conv3_flat = tf.reshape(bn3, [-1, 5 * 5 * 48])
            dense = tf.layers.dense(inputs=conv3_flat, units=128, activation=tf.nn.relu,name="dense",kernel_initializer=tf.contrib.layers.xavier_initializer())
            logits= tf.layers.dense(inputs=dense, units=2, activation=tf.nn.relu,name="logits",kernel_initializer=tf.contrib.layers.xavier_initializer())
          
    return logits

3.train.py

from dataset import *
from net import simpleconv3
import sys
import os
import cv2

txtfile = sys.argv[1]
batch_size = 64
num_classes = 2
image_size = (48,48)
learning_rate = 0.0001

debug=False

if __name__=="__main__":
    '''获取数据'''
    dataset = ImageData(txtfile,batch_size,num_classes,image_size)
    iterator = dataset.data.make_one_shot_iterator()
    dataset_size = dataset.dataset_size    # 训练集数据大小
    batch_images,batch_labels = iterator.get_next()
    '''开始训练'''
    Ylogits = simpleconv3(batch_images,True)
    print("Ylogits size=",Ylogits.shape)
    Y = tf.nn.softmax(Ylogits)
    cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits=Ylogits, labels=batch_labels)
    cross_entropy = tf.reduce_mean(cross_entropy)   # 损失函数  
    correct_prediction = tf.equal(tf.argmax(Y, 1), tf.argmax(batch_labels, 1))  

    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))     # 计算正确率
    
    update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
    with tf.control_dependencies(update_ops):
        train_step = tf.train.AdamOptimizer(learning_rate).minimize(cross_entropy)  
    '''保存模型'''
    saver = tf.train.Saver()
    in_steps = 100
    checkpoint_dir = 'checkpoints/'
    if not os.path.exists(checkpoint_dir):
        os.mkdir(checkpoint_dir)
    log_dir = 'logs/'
    if not os.path.exists(log_dir):
        os.mkdir(log_dir)
    summary = tf.summary.FileWriter(logdir=log_dir)
    loss_summary = tf.summary.scalar("loss", cross_entropy)
    acc_summary = tf.summary.scalar("acc", accuracy)
    image_summary = tf.summary.image("image", batch_images)

    with tf.Session() as sess:  
        init = tf.global_variables_initializer()
        sess.run(init)  
        steps = 10000  
        for i in range(steps): 
            _,cross_entropy_,accuracy_,batch_images_,batch_labels_,loss_summary_,acc_summary_,image_summary_ = sess.run([train_step,cross_entropy,accuracy,batch_images,batch_labels,loss_summary,acc_summary,image_summary])
            if i % in_steps == 0 :
                print(i,"iterations,loss=",cross_entropy_,"acc=",accuracy_)
                saver.save(sess, checkpoint_dir + 'model.ckpt', global_step=i)    
                summary.add_summary(loss_summary_, i)
                summary.add_summary(acc_summary_, i)
                summary.add_summary(image_summary_, i)
                #print "predict=",Ylogits," labels=",batch_labels

              

4.inference.py 测试接口

python inference.py ./checkpoints/model.ckpt-9900 ./val_shuffle.txt

'''
@ count 总的图片数量
@ posacc 正的样本
@ negcount 负的样本
'''
import tensorflow as tf
from net import simpleconv3
import sys
import numpy as np
import cv2
import os

testsize = 48
x = tf.placeholder(tf.float32, [1,testsize,testsize,3])
y = simpleconv3(x,False)
y = tf.nn.softmax(y)

lines = open(sys.argv[2]).readlines()  # 从外部加载数据
count = 0
acc = 0
posacc = 0
negacc = 0
poscount = 0
negcount = 0

with tf.Session() as sess:  
    init = tf.global_variables_initializer()
    sess.run(init)  
    saver = tf.train.Saver()
    saver.restore(sess,sys.argv[1])  # 加载模型
    
    #test one by one, you can change it into batch inputs
    for line in lines:
        imagename,label = line.strip().split(' ')
        
        img = tf.read_file(imagename)   # 读取图片
        img = tf.image.decode_jpeg(img,channels = 3)  # 图像解码
        img = tf.image.convert_image_dtype(img,dtype = tf.float32)  # 改变图像数据类型
        img = tf.image.resize_images(img,(testsize,testsize),method=tf.image.ResizeMethod.NEAREST_NEIGHBOR)
        img = tf.image.per_image_standardization(img)  # 归一化

        imgnumpy = img.eval()  # 将tensor对象转成数组  imgnumpy(48,18,3)
        imgs = np.zeros([1,testsize,testsize,3],dtype=np.float32)  # imgs=(1,48,48,3)
        imgs[0:1,] = imgnumpy

        result = sess.run(y, feed_dict={x:imgs})
        result = np.squeeze(result)  # 即把shape中为1的维度去掉
        '''结果判断'''
        if result[0] > result[1]:    
            predict = 0
        else:    
            predict = 1

        count = count + 1
        if str(predict) == '0':
            negcount = negcount + 1
            if str(label) == str(predict):
                negacc = negacc + 1
                acc = acc + 1
        else:
            poscount = poscount + 1
            if str(label) == str(predict):
                posacc = posacc + 1
                acc = acc + 1
    
        print(result)
print("acc = ",float(acc) / float(count))
print("poscount=",poscount)
print("posacc = ",float(posacc) / float(poscount))
print("negcount=",negcount)
print("negacc = ",float(negacc) / float(negcount))

### 文本分类学习笔记与资料 文本分类是自然语言处理领域的重要任务之一,旨在将文本分配到一个或多个预定义的类别中。以下是关于文本分类的学习笔记及相关资料。 #### 1. 文本分类的基本方法 文本分类可以分为传统方法和深度学习方法。传统方法通常依赖于特征工程,例如使用TF-IDF(词频-逆文档频率)提取文本特征,并结合机器学习算法如SVM、朴素贝叶斯等进行分类[^2]。深度学习方法则通过神经网络模型自动提取特征并完成分类任务,例如使用BERT、LSTM等模型[^3]。 #### 2. 使用TF-IDF进行文本分类 TF-IDF是一种常用的文本特征提取方法,能够反映一个词语对于文档的重要性。以下是一个使用TF-IDF进行文本分类的Python代码示例: ```python from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.naive_bayes import MultinomialNB from sklearn.pipeline import make_pipeline from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score # 示例数据集 texts = ["这是一个正面的例子", "这是一个负面的例子", "正面情绪很高涨", "负面情绪很强烈"] labels = [1, 0, 1, 0] # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(texts, labels, test_size=0.25, random_state=42) # 创建TF-IDF向量化器和朴素贝叶斯分类器的流水线 model = make_pipeline(TfidfVectorizer(), MultinomialNB()) # 训练模型 model.fit(X_train, y_train) # 预测并评估准确率 y_pred = model.predict(X_test) print("Accuracy:", accuracy_score(y_test, y_pred)) ``` 上述代码展示了如何使用TF-IDF向量化器和朴素贝叶斯分类器构建一个简单的文本分类模型。 #### 3. 使用BERT进行文本分类 BERT是一种预训练语言模型,能够捕获上下文信息,适用于多种NLP任务,包括文本分类。以下是一个使用BERT进行文本分类的简化流程: - **数据准备**:加载并预处理文本数据,转换为BERT输入格式。 - **模型定义**:加载预训练的BERT模型,并在其顶部添加全连接层。 - **训练与评估**:使用交叉熵损失函数训练模型,并在测试集上评估性能。 ```python import torch from transformers import BertTokenizer, BertForSequenceClassification # 加载预训练BERT模型和分词器 tokenizer = BertTokenizer.from_pretrained(&#39;bert-base-chinese&#39;) model = BertForSequenceClassification.from_pretrained(&#39;bert-base-chinese&#39;, num_labels=2) # 示例句子 sentence = "这是一个正面的例子" inputs = tokenizer(sentence, return_tensors="pt", padding=True, truncation=True, max_length=128) # 模型预测 outputs = model(**inputs) logits = outputs.logits predicted_class = torch.argmax(logits, dim=-1) print("Predicted Class:", predicted_class.item()) ``` 上述代码展示了如何加载预训练的BERT模型并进行文本分类预测。 #### 4. 数据预处理与增强 在文本分类任务中,数据的质量和数量对模型性能有重要影响。数据预处理步骤包括去除停用词、标点符号、数字等无关信息,并进行分词处理。此外,可以通过数据增强技术增加训练数据的多样性,例如同义词替换、随机插入等方法[^2]。 #### 5. 模型评估与优化 模型评估常用指标包括准确率、精确率、召回率和F1分数。为了提高模型性能,可以采用超参数调优、模型集成等策略。此外,低秩适配(LoRA)、量化微调(QLoRA)等技术也可以用于减少模型训练成本并提升效果[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值