VGG-Bayes图像识别,基于贝叶斯定理

贝叶斯法则

通常,事件A在事件B(发生)的条件下的概率,与事件B在事件A的条件下的概率是不一样的;然而,这两者是有确定的关系,贝叶斯法则就是这种关系的陈述。

作为一个规范的原理,贝叶斯法则对于所有概率的解释是有效的;然而,频率主义者和贝叶斯主义者对于在应用中概率如何被赋值有着不同的看法:频率主义者根据随机事件发生的频率,或者总体样本里面的个数来赋值概率;贝叶斯主义者要根据未知的命题来赋值概率。一个结果就是,贝叶斯主义者有更多的机会使用贝叶斯法则。

贝叶斯法则是关于随机事件A和B的条件概率边缘概率的。

P(A_{i}|B)=\frac{P(B|A_{i})P(A_{i})}{\sum_{j}P(B|A_{J})P(A_{j})}

其中P(A|B)是在B发生的情况下A发生的可能性。A_{1},...,A_{n}为完备事件组,即U_{i=1}^{n}A_{i} = \Omega ,A_{i}A_{j} = \Phi ,P(A_{i})>0

贝叶斯法则中,每个名词都有约定俗成的名称:

Pr(A)是A的先验概率或边缘概率。之所以称为"先验"是因为它不考虑任何B方面的因素。

Pr(A|B)是已知B发生后A的条件概率,也由于得自B的取值而被称作A的后验概率

Pr(B|A)是已知A发生后B的条件概率,也由于得自A的取值而被称作B的后验概率。

Pr(B)是B的先验概率或边缘概率,也作标准化常量(normalized constant)。

按这些术语,Bayes法则可表述为:

后验概率 = (似然度 * 先验概率)/标准化常量 也就是说,后验概率与先验概率和似然度的乘积成正比。

另外,比例Pr(B|A)/Pr(B)也有时被称作标准似然度(standardised likelihood),Bayes法则可表述为:

后验概率 = 标准似然度 * 先验概率。 [1] 

贝式定理

对于变量有二个以上的情况,贝式定理亦成立。例如:

P(A|B,C)=\frac{P(C|A,B)P(A)P(B|A)}{P(B)P(C|B)}

这个式子可以由套用多次二个变量的贝氏定理及条件机率的定义导出。

本文使用数据集是Sort_1000pics,并对数据进行了分类,使用VGG对分类后的数据集特征提取,对得到的数据集使用贝叶斯原理进行训练识别。

数据集分类代码

import os
import shutil
import glob


def mycopyfile(srcfile, dstpath, numlist):  # 复制函数
    if not os.path.isfile(srcfile):
        print("%s not exist!" % (srcfile))
    else:
        fpath, fname = os.path.split(srcfile)  # 分离文件名和路径
        num = str.split(fname, '.')[0]
        if not os.path.exists(dstpath + fname):
            if numlist <= int(num) <= numlist + 99:
                shutil.copyfile(srcfile, dstpath + fname)
                print("copy %s -> %s" % (srcfile, dstpath + fname))
        else:
            print("{}.{} file exist!".format(str.split(fname, '.')[0], str.split(fname, '.')[1]))


dirlist = ['People', 'Architecture', 'Beach', 'BigTrucks', 'Dinosaurs', 'Elephant', 'Flowers', 'Food', 'Horse',
           'Mountain']
numlist = [0, 200, 100, 300, 400, 500, 600, 900, 700, 800]
dirnumdict = dict(zip(dirlist, numlist))
print(dirnumdict)
src_dir = os.getcwd() + '/dataset1/'
if os.path.isdir(src_dir):
    print(True)
src_file_list = glob.glob(src_dir + '*')
for eachdir in dirlist:
    dst_dir = os.getcwd() + '/dataset/{}/'.format(eachdir)
    for srcfile in src_file_list:
        mycopyfile(srcfile, dst_dir, dirnumdict[eachdir])

VGG特征提取代码

import torch
import torch.nn as nn
from torch.autograd import Variable
from torchvision import models, transforms
from PIL import Image
import numpy as np
import os, glob
import csv

dir_root = './dataset/'
features_dir = './dataset/feature/'  # Resnet_features_train

class Encoder(nn.Module):
    def __init__(self):
        super(Encoder, self).__init__()
        VGG = models.vgg16(pretrained=True)
        self.feature = VGG.features
        self.classifier = nn.Sequential(*list(VGG.classifier.children())[:-3])
        pretrained_dict = VGG.state_dict()
        model_dict = self.classifier.state_dict()
        pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict}
        model_dict.update(pretrained_dict)
        self.classifier.load_state_dict(model_dict)

    def forward(self, x):
        output = self.feature(x)
        output = output.view(output.size(0), -1)
        output = self.classifier(output)
        return output


model = Encoder()
#model = model.cuda()


def extractor(img_path, saved_path, net, use_gpu=False):
    transform = transforms.Compose([
        transforms.Resize(256),
        transforms.CenterCrop(224),
        transforms.ToTensor()]
    )

    img = Image.open(img_path)
    img = transform(img)
    print(img.shape)

    x = Variable(torch.unsqueeze(img, dim=0).float(), requires_grad=False)
    print(x.shape)

    if use_gpu:
        x = x.cuda()
        net = net.cuda()
    y = net(x).cpu()
    y = torch.squeeze(y)
    y = y.data.numpy()
    feature_numpy = y
    print(y.shape)
    np.savetxt(saved_path, y, delimiter=',')
    return feature_numpy


if __name__ == '__main__':
    extensions = ['jpg', 'jpeg', 'JPG', 'JPEG']
    mkdictten = {}
    print(os.listdir(dir_root))
    feature_list = []
    lable_name = []

    for eachfilename in os.listdir(dir_root):
        if eachfilename != 'feature':
            data_dir = './dataset/{}'.format(eachfilename)  # train
            files_list = []
            x = os.walk(data_dir)
            for path, d, filelist in x:
                for filename in filelist:
                    file_glob = os.path.join(path, filename)
                    files_list.extend(glob.glob(file_glob))

            print(files_list)

            use_gpu = torch.cuda.is_available()

            for x_path in files_list:
                file_name = x_path.split('\\')[-1].split('.')[0]
                file_feature_dir = features_dir+x_path.split('/')[-1].split('\\')[0]
                print(file_name)
                if not os.path.exists(file_feature_dir):
                    os.makedirs(file_feature_dir)
                fx_path = file_feature_dir + '/' + file_name + '.txt'
                if not os.path.exists(fx_path):
                    feature_numpy = extractor(x_path, fx_path, model, use_gpu)
                    feature_list.append(list(feature_numpy))
                    lable_name.append(eachfilename)

                else:
                    print("{} file exist!".format(fx_path))
with open('labelset.csv','w') as f:
    f_csv = csv.writer(f)
    #f_csv.writerow(feature_list)
    f_csv.writerow(lable_name)
with open('dataset.csv', 'w') as f:
    f_csv = csv.writer(f)
    f_csv.writerows(feature_list)

贝叶斯图像分类识别代码

from sklearn.model_selection import train_test_split #对数据集进行切分
from sklearn.naive_bayes import GaussianNB  # 朴素贝叶斯网络模型

import csv
X = []
with open('dataset.csv', 'r') as f:
    reader = csv.reader(f)
    for row in reader:
        float_row = []
        if len(row):
            for each in row:
                float_row.append(float(each))
            X.append(float_row)


with open('labelset.csv','r') as f:
    f_csv = csv.reader(f)
    rows = [row for row in f_csv]
Y = rows[0]


X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.2, random_state=0)

#将数据集按照 训练集比测试集为8:2的比例随机拆分数据集
clf = GaussianNB()  # 建立朴素贝叶斯网络
clf.fit(X_train, y_train)  # 带入训练集训练模型
pre = clf.predict(X_test)  # 预测测试集中特征矩阵所属的类别
print('预测集标签')
print(y_test)
print('预测结果')
print(pre)
num = 0
for i in range(0,len(pre)):
    if y_test[i] == pre[i]:
        num += 1
print(num/len(pre))

with open('result.csv','w') as f:
    f_csv = csv.writer(f)
    #f_csv.writerow(feature_list)
    f_csv.writerow(['预测试集标签'])
    f_csv.writerow(y_test)
    f_csv.writerow(['预测结果标签'])
    f_csv.writerow(pre)
    f_csv.writerow(['精度:{}'.format(num/len(pre))])

测试结果:

预测试集标签
PeopleMountainBigTrucksFlowersFoodPeopleArchitectureBigTrucksDinosaursHorseElephantFlowersHorseBigTrucksFlowersArchitecturePeopleBeachArchitectureArchitectureArchitectureElephantDinosaursDinosaursMountainHorseArchitectureBeachHorseArchitectureMountainHorseFoodHorseElephantHorsePeopleDinosaursPeopleBigTrucksBigTrucksPeopleFoodFoodBigTrucksHorseMountainBeachDinosaursFlowersDinosaursBigTrucksBigTrucksElephantMountainFlowersBigTrucksBigTrucksPeopleDinosaursFlowersFoodBeachBigTrucksElephantBeachBigTrucksFlowersBigTrucksFlowersHorseBigTrucksHorseBigTrucksPeopleElephantDinosaursHorseFoodFoodBigTrucksElephantDinosaursPeoplePeopleFoodBigTrucksFlowersElephantMountainElephantElephantPeopleBigTrucksFoodElephantFlowersBeachDinosaursFoodHorseMountainArchitecturePeopleDinosaursFoodFoodHorsePeopleBigTrucksArchitectureFlowersElephantFlowersBigTrucksDinosaursFlowersDinosaursElephantFlowersHorsePeopleBeachPeopleArchitectureMountainDinosaursBigTrucksPeopleFoodElephantFoodFlowersHorseHorseFoodDinosaursArchitectureFlowersMountainBeachFoodFlowersBigTrucksBigTrucksElephantDinosaursDinosaursArchitectureArchitectureBigTrucksArchitectureElephantHorsePeoplePeopleElephantDinosaursMountainElephantFlowersPeopleFoodMountainPeopleDinosaursDinosaursPeopleDinosaursElephantPeopleHorseBeachMountainElephantHorseBigTrucksFoodMountainBeachHorsePeopleElephantDinosaursPeoplePeopleHorseElephantHorseBigTrucksMountainMountainElephantArchitectureHorseFoodHorseBigTrucksFoodBeach
预测结果标签
PeoplePeopleBigTrucksFlowersFoodBeachArchitectureBigTrucksDinosaursHorseElephantFlowersHorseBigTrucksFlowersArchitectureBeachBeachArchitectureArchitectureArchitectureElephantDinosaursDinosaursMountainHorseArchitectureBeachHorseArchitectureMountainHorseFoodHorseElephantHorsePeopleDinosaursPeopleBigTrucksBigTrucksPeopleFoodFoodBigTrucksHorseMountainMountainDinosaursFlowersDinosaursBigTrucksBigTrucksElephantMountainFlowersBigTrucksBigTrucksPeopleDinosaursFlowersPeopleBeachBigTrucksElephantBeachBigTrucksFlowersBigTrucksFoodHorseBigTrucksHorseBigTrucksPeopleElephantDinosaursHorseFoodFoodBigTrucksElephantDinosaursPeopleBeachFoodBigTrucksFlowersElephantMountainElephantElephantPeopleBigTrucksFoodElephantFlowersFoodDinosaursFoodHorseMountainArchitecturePeopleDinosaursFoodFoodHorsePeopleBigTrucksBeachFlowersElephantFlowersBigTrucksDinosaursFlowersDinosaursElephantFlowersHorsePeopleBeachPeopleArchitectureMountainDinosaursBigTrucksPeoplePeopleElephantFoodFlowersBeachHorseFoodDinosaursArchitectureFlowersBeachBeachFoodFlowersBigTrucksBigTrucksElephantDinosaursDinosaursBeachBeachBigTrucksArchitectureElephantHorsePeoplePeopleElephantDinosaursBeachElephantFlowersFoodFoodElephantPeopleDinosaursDinosaursPeopleDinosaursElephantPeopleHorseBeachMountainElephantHorseBigTrucksPeopleMountainBeachElephantPeopleElephantDinosaursPeoplePeopleHorseElephantHorseBigTrucksMountainMountainElephantArchitectureHorsePeopleHorseBigTrucksFoodBeach
精度:0.9
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
VGG-16是一种卷积神经网络模型,用于图像识别任务。猫狗识别是指利用计算机视觉技术对图像中的猫和狗进行分类和识别的任务。 VGG-16模型是由牛津大学的研究团队于2014年提出的。该模型的名称VGGVGGNet的缩写,其中16表示该模型有16个卷积层和全连接层。VGG-16模型通过一系列的卷积层和池化层来提取图像的特征,然后通过全连接层和Softmax分类器对提取的特征进行分类。 对于猫狗识别任务,首先需要准备一个具有大量猫和狗图像的数据集,并标记每个图像的类别。将这个数据集划分为训练集和测试集。 然后,使用VGG-16模型对训练集的图像进行训练,通过反向传播算法不断优化模型的权重参数,使其能够准确地识别猫和狗。在训练过程中,可以使用一些优化技巧,如学习率调整、数据增强等,来提高模型的性能和鲁棒性。 训练完成后,使用训练好的模型对测试集的图像进行分类预测。将预测结果与实际标签进行比较,计算准确率和其他评价指标来评估模型的性能。 通过以上步骤,可以利用VGG-16模型对猫和狗的图像进行准确的分类识别。然而,模型的性能可能会受数据集的质量和多样性、模型的超参数设置等因素的影响。因此,在实际应用中,可以根据具体需求对模型进行调优,并采用一些先进的方法来进一步提高识别的准确性和泛化能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想成专家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值