0
点赞
收藏
分享

微信扫一扫

图像识别2:多分类及线性模型实验

图像识别2:多分类及线性模型实验

一、实验目的

基于相似性度量和最短距离法的多分类实验,通过曲线图分析测试集噪声对两种方法的影响。熟悉线性模型,进行线性回归和线性判别实验。

二、实验内容

  1. 将 MIT 室内场景数据库中机场、面包房、卧室、浴室作为四个类别。利用留出法(比例 2:1)、交叉验证法(k 取 10)分别完成训练集与测试集的划分,并使用夹角余弦、距离进行多分类,给出分类准确率。
  2. 对测试集添加椒盐噪声,记录当噪声密度 d 取 0,0.01,0.05,0.1,0.2,0.5,0.8,1 时的分类精度,并画出精度曲线图,通过曲线图分析测试集噪声对两种方法的影响。
  3. 根据梯度下降法、闭式解完成一元线性回归实验,并比较两种解下的实验结果。
  4. 根据训练数据,学习投影矩阵。然后将 LDA 在训练样本上的低维表示结果可视化。最后使用距离最短对测试样本进行分类。

(1)算法设计及实现

1. a 次 b 折交叉验证法(k 取 10)完成训练集与测试集的划分。

b 折交叉验证标签:将标签均分成 b 份,每一份打上不同的记号,共 b 个记号。得到样本被不同的数打标签,同样的标签数就是一份,一共是 b 份。
a 次交叉验证划分:b 次循环,每一次取其中一份 j(1:b)作为测试集,其余的(~ctest)做训练集。

在这里插入图片描述

2. 对测试集添加椒盐噪声,记录当噪声密度 d 取 0,0.01,0.05,0.1,0.2,0.5,0.8,1 时的分类精度,并画出精度曲线图,通过曲线图分析测试集噪声对两种方法的影响。

设置参数:将噪声 d 封装成一维矩阵,依次读取 7 种椒盐噪声。
在这里插入图片描述
加入椒盐噪声:通过 imnoise 函数给测试集加入椒盐噪声,然后对除 Label 标签外的部分归一化,最后拼接。
在这里插入图片描述
分别计算不同噪声的分类精度。
在这里插入图片描述
绘图分析影响。这里通过学习 CSDN 上好看的 matlab 绘图,了解到了一系列可以改进图形的参数,借鉴其并将它们套用于本实验中。
在这里插入图片描述

  1. 根据梯度下降法、闭式解完成一元线性回归实验,并比较两种解下的实
    验结果。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    划分训练集和测试集比例(1:2 划分)。通过 randperm 函数得到一个打乱序列的 b,该序列包含(1,n),本文中 n 为合并后矩阵的行数。由于题目要求的 1:2 划分容易出现不完美分割的情况,因此对划分的数量进行取整操作。然后 c,d 两个序列分别取打乱序列的前 33%、后 66%,根据 c,d 两个序列的数值取原矩阵对应的列数,最后将按顺序将每次划分结果对应保存于对应的训练集和测试集中,并分别绘制训练集和测试集的散点图。
    遍历测试集与训练集,计算两者两两之间的欧式距离。绘图展示梯度下降
    线性回归,最小二乘线性回归的图像。
    在这里插入图片描述

  2. 根据训练数据,学习投影矩阵。然后将 LDA 在训练样本上的低维表示结果可视化。最后使用距离最短对测试样本进行分类。
    首先定义线性判别回归函数 LDA。其中,mappedX 为低维数据降维后的坐标,mapping 为映射的信息,M 为,X 为样本矩阵,label 为样本标签,no_dims: 投影空间(低维空间)的维度。
    在这里插入图片描述

初始化。①设置特征默认维数为 2,提高函数的复用性。然后通过②bsxfun 函数对函数进行标准化,优点为当 A 和 B 的维度不相等,并且 A 和 B各自有一个维度为 1 时,函数自动调整维度,目的也是提高函数复用性。之后③去掉矩阵标签中重复的元素,将标签类别保存于 unique 中。最后初始化用到的矩阵。
通过①计算总协方差矩阵(全局散度矩阵)St = np.dot((X - mean).T, X - mean),②St = np.dot((X - mean).T, X - mean),③全局散度矩阵 St=Sw+Sb,所以 Sb = St-Sw 三个式子计算类内离散度矩阵 Sw。同时确保降维后的特征点维度小于 max,提高代码的安全性。
在这里插入图片描述

按降序排列特征值和特征向量。M 变换矩阵由 v 的最大的 nc-1 个特征值所对应的特征向量构成。对 inv(Sw)*Sb 进行特征分解[V,D]=eig(A,B) eig(A,B)返回方阵 A 和 B 的 N 个广义特征值,构成 N×N 阶对角阵 D, 其对角线上的N 个元素即为相应的广义特征值,同时将返回相应的特征向量构成 N×N 阶满秩矩阵,且满足 AV=BVD。之后判断数组的元素是否是 NaN,并提取前no_dims 个特征向量。
在这里插入图片描述

最后计算投影后的(二维)坐标值。
在这里插入图片描述

主函数部分,先通过 xlsread 或 csread 函数读取 csv 文件数据。
在这里插入图片描述

在 LDA 多分类后,将返回的四维降维成的二维坐标值反应到图像上,通过不同颜色和形状区分不同的标签,计算坐标两两之间的欧氏距离。

三、实验结果:

在这里插入图片描述

这个结果很奇怪,但检查后感觉代码逻辑没有问题,因此试图分析:
欧式距离和夹角余弦预测结果几乎都是标签 1,可能是由于样本 1 的数量相较于其他的 2、3、4,导致标签 1“过拟合”。
检查过程中的问题及解决:
在这里插入图片描述

结果全一样明显不对,看工作区变量发现,需要进行处理。查看该文件下的图片,发现大多数为二维,因此增加一行判断语句,如果是 rgb 三维图像,转化为二维,否则不转化。

 if(ndims(img_origin)==3) 
 I1=rgb2gray(img_origin); 
 end

将其改为 length 函数。
梯度下降得到的 theta 的值:
w:1.159369,
b:-3.369070
梯度下降法一元回归的欧式距离为 591.925823,
闭式解为 594.443011
在这里插入图片描述

可以得到结果,梯度下降和最小二乘线性回归的直线几乎重合,差别不大。
训练集[日本,中国]的标签分别为 1,2。
结果很合适,可以看到点就在散点图聚集处。

四、实验心得:

通过本次实验,熟练掌握了基于相似性度量和最短距离法的多分类方法,以及 a 次 b 折交叉验证法,并通过曲线图分析测试集噪声对两种方法的影响。在线性回归和线性判别实验中,了解了机器学习的数学公式及实践原理,对损失函数、梯度下降有了实际的认识,对其数学与编程的应用中有了更深的理解。在网络平台资源的学习下,能通过多种方案编写代码达到同一个目的,并且代码的复用性和安全性得到了较大的提升。并且尝试根据运行结果改进代码未报错但存在的问题,使代码更符合数学原理。

五、实验源码:

实验五1.0版本(1)——夹角余弦

1.0版本仅记录成长,无参考价值。时空复杂度相较后面都太高了。

% 1.将MIT室内场景数据库中机场、面包房、卧室、浴室作为四个类别。
% 利用留出法完成训练集与测试集的划分(比例2:1),
% 并使用夹角余弦、距离进行多分类,给出分类准确率。
%% 设置参数
clc;clear;close all; 
path='D:\Desktop\大三上\神经网络\实验三\数据\MIT室内场景';
path1='D:\Desktop\大三上\神经网络\实验四\MIT室内场景2';
ObjDir1='\airport_inside';
ObjDir2='\bakery';
ObjDir3='\bathroom';
ObjDir4='\bedroom';
a=1; %留出法划分次数
%% 读取指定路径下单个文件夹所有图像
%% 读取机场的图片并处理
cd ([path,ObjDir1]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi1=zeros(img_num,64*64);

for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi1
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi1(pn,:)=double(reshape(Image,1,[]));
end
% 将机场作为样本1,给出训练样本的标签Xlabel
XLable=ones(img_num,1);
phi1=[phi1 XLable];
%% 读取面包房的图片并处理
cd ([path,ObjDir2]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi2=zeros(img_num,64*64);

for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi2(pn,:)=double(reshape(Image,1,[]));
end
% 将面包房作为样本2,给出训练样本的标签Xlabel
XLable=2*ones(img_num,1);
phi2=[phi2 XLable];
%% 读取卧室的图片并处理
cd ([path1,ObjDir3]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi3=zeros(img_num,64*64);
for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi3
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi3(pn,:)=double(reshape(Image,1,[]));
end
% 将浴室作为样本3,给出训练样本的标签Xlabel
XLable=ones(img_num,1);
phi3=[phi3 XLable];
%% 读取浴室的图片并处理
cd ([path1,ObjDir4]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi4=zeros(img_num,64*64);
for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    % I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi4(pn,:)=double(reshape(Image,1,[]));
end
% 将卧室作为样本4,给出训练样本的标签Xlabel
XLable=zeros(img_num,1);
phi4=[phi4 XLable];
%% 列拼接四个矩阵并归一化
phi=[phi1;phi2;phi3;phi4];
% 矩阵归一化
phihead=phi(:,1:end-1);
[phihead,PS]=mapminmax(phihead); %[phi,PS]中phi为归一化后数值,PS为一种对应关系
% phi(1:end-1,:)为除标签栏(最后一列)之外归一化
phi=[phihead,phi(:,end)];
%% 留出法划分互斥的训练集和测试集
% 二维数组a次二划分
for i=1:a
    % 划分训练集和测试集比例(2:1划分)
    b=randperm(length(phi(:,1))); %打乱列序列
    e=round(length(phi(:,1))*2/3);
    c=b(1:e); %取打乱序列的前60%
    d=b(e+1:end); %取打乱序列的后40% %end直到数组结尾
    
    atrain=phi(c,:); %(:,:)为取原矩阵行和列,(:,1:50)为取原矩阵列,行取前60%
    atest=phi(d,:); %(:,d)为取原矩阵列,行取随机40%的行
    Xtrain{1,i}=atrain; %保存在train的(1,1)cell
    Xtest{1,i}=atest;
end
%% 保存五次二划分的数据集
save ('Xtrain.mat','Xtrain');
save ('Xtest.mat','Xtest');
save('A.mat','a');
% 读取五次二划分
clear;clc
load Xtrain.mat
load Xtest.mat
load A.mat
%% 夹角余弦判断测试集和哪个训练集最相似,然后把该训练集的标签给该测试集
for i=1:a % a为二划分次数
    % {}为元胞数组
    btrain=Xtrain{1,i}; %读取保存在train的(1,1)cell
    btest=Xtest{1,i};
    tempdis=-inf;tempj=0;
    Xlable{1,i}=zeros(1,size(btest,1));
    count=0; % 记录错误个数
    for j=1:size(btest,1) % 测试集的几行数据逐一进行比对
        test{1,j}=ones(size(btest,2),1); % size(A,2)得到A的列数
        test{1,j}=btest(j,:);
        Xlable{1,i}(j)=test{1,j}(1,end);  % 读取测试集标签
        for k=1:size(btrain,1) % 分别与训练集的几行数据一一比对
            train{1,k}=ones(size(btrain,2),1); 
            train{1,k}=btrain(k,:);
            % 计算两者之间的夹角余弦
            B=[test{1,j};train{1,k}]; %将后续进行计算的两行代码放到一个矩阵
            distance=1-pdist(B,'cosine'); %计算夹角余弦
            if(distance>tempdis) %余弦值越接近1,两个向量越相似
                tempdis=distance;tempj=k; % 如果距离最大则判断为同一类型
                % test{1,j}(1,end)=train{1,k}(1,end); % 将夹角余弦最短的训练集标签赋值给测试集
                res=train{1,k}(1,end);
            end
        end
        ress(j)=res;
        % 计算错误个数
        if(res~=Xlable{1,i}(j))
            count=count+1;
        end
    end
    % 计算每个测试集的准确率
    rateture(i)=1-count/size(btest,1);
    % sprintf('正确率为:%.2f',rateture)
end
%% 计算a次划分的准确率均值
meanture=mean(rateture(:));
sprintf('夹角余弦的正确率为:%.2f',meanture)

实验五1.0版本(2)——欧式距离

% 1.将MIT室内场景数据库中机场、面包房、卧室、浴室作为四个类别。
% 利用留出法完成训练集与测试集的划分(比例2:1),
% 并使用夹角余弦、距离进行多分类,给出分类准确率。
%% 设置参数
clc;clear;close all; 
path='D:\Desktop\大三上\神经网络\实验三\数据\MIT室内场景';
path1='D:\Desktop\大三上\神经网络\实验四\MIT室内场景2';
ObjDir1='\airport_inside';
ObjDir2='\bakery';
ObjDir3='\bathroom';
ObjDir4='\bedroom';
a=1; %留出法划分次数
%% 读取指定路径下单个文件夹所有图像
%% 读取机场的图片并处理
cd ([path,ObjDir1]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi1=zeros(img_num,64*64);

for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi1
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi1(pn,:)=double(reshape(Image,1,[]));
end
% 将机场作为样本1,给出训练样本的标签Xlabel
XLable=ones(img_num,1);
phi1=[phi1 XLable];
%% 读取面包房的图片并处理
cd ([path,ObjDir2]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi2=zeros(img_num,64*64);

for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi2(pn,:)=double(reshape(Image,1,[]));
end
% 将面包房作为样本2,给出训练样本的标签Xlabel
XLable=2*ones(img_num,1);
phi2=[phi2 XLable];
%% 读取卧室的图片并处理
cd ([path1,ObjDir3]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi3=zeros(img_num,64*64);
for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi3
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi3(pn,:)=double(reshape(Image,1,[]));
end
% 将浴室作为样本3,给出训练样本的标签Xlabel
XLable=ones(img_num,1);
phi3=[phi3 XLable];
%% 读取浴室的图片并处理
cd ([path1,ObjDir4]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi4=zeros(img_num,64*64);
for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    % I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi4(pn,:)=double(reshape(Image,1,[]));
end
% 将卧室作为样本4,给出训练样本的标签Xlabel
XLable=zeros(img_num,1);
phi4=[phi4 XLable];
%% 列拼接四个矩阵
phi=[phi1;phi2;phi3;phi4];
%% 留出法划分互斥的训练集和测试集
% 二维数组a次二划分
for i=1:a
    % 划分训练集和测试集比例(2:1划分)
    b=randperm(length(phi(:,1))); %打乱列序列
    e=round(length(phi(:,1))*2/3);
    c=b(1:e); %取打乱序列的前60%
    d=b(e+1:end); %取打乱序列的后40% %end直到数组结尾
    
    atrain=phi(c,:); %(:,:)为取原矩阵行和列,(:,1:50)为取原矩阵列,行取前60%
    atest=phi(d,:); %(:,d)为取原矩阵列,行取随机40%的行
    Xtrain{1,i}=atrain; %保存在train的(1,1)cell
    Xtest{1,i}=atest;
end
%% 保存五次二划分的数据集
save ('Xtrain.mat','Xtrain');
save ('Xtest.mat','Xtest');
save('A.mat','a');
% 读取五次二划分
clear;clc
load Xtrain.mat
load Xtest.mat
load A.mat
%% 欧式距离判断测试集和哪个训练集最相似,然后把该训练集的标签给该测试集
for i=1:a % a为二划分次数
    % {}为元胞数组
    btrain=Xtrain{1,i}; %读取保存在train的(1,1)cell
    btest=Xtest{1,i};
    tempdis=inf;tempj=0;
    Xlable=zeros(1,size(btest,1));
    flag=0; % 记录错误个数
    for j=1:size(btest,1) % 测试集的几行数据逐一进行比对
        test{1,j}=ones(size(btest,2),1); % size(A,2)得到A的列数
        test{1,j}=btest(j,:);
        Xlable(j)=test{1,j}(1,end);  % 读取测试集标签
        for k=1:size(btrain,1) % 分别与训练集的几行数据一一比对
            train{1,k}=ones(size(btrain,2),1); 
            train{1,k}=btrain(k,:);
            % 计算两者之间的欧式距离
            distance=sqrt(sum(abs(test{1,j}-train{1,k})).^2);  %sum(x.^2)计算数组的平方和
            if(distance<tempdis)
                tempdis=distance;tempj=k; % 如果距离最小则判断为同一类型
                res=train{1,k}(1,end); % 将最短距离的训练集标签赋值给测试集
            end
        end
        ress(j)=res;
        % 计算夹角余弦的错误个数
        if(res~=Xlable(j))
            flag=flag+1;
        end
    end
    % 计算每个测试集的准确率
    rateture(i)=1-flag/size(btest,1);
    % sprintf('错误率为:%.2f   正确率为:%.2f',rateerrors,rateture)
end
%% 计算a次划分的准确率均值
meanture=mean(rateture(:));
sprintf('欧式距离的正确率为:%.2f',meanture)

实验五1.0版本(3)——夹角余弦和欧式距离

% 1.将MIT室内场景数据库中机场、面包房、卧室、浴室作为四个类别。
% 利用留出法完成训练集与测试集的划分(比例2:1),
% 并使用夹角余弦、距离进行多分类,给出分类准确率。
%% 设置参数
clc;clear;close all; 
path='D:\Desktop\大三上\神经网络\实验三\数据\MIT室内场景';
path1='D:\Desktop\大三上\神经网络\实验四\MIT室内场景2';
ObjDir1='\airport_inside';
ObjDir2='\bakery';
ObjDir3='\bathroom';
ObjDir4='\bedroom';
a=2; %留出法划分次数
%% 读取指定路径下单个文件夹所有图像
%% 读取机场的图片并处理
cd ([path,ObjDir1]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi1=zeros(img_num,64*64);

for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi1
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi1(pn,:)=double(reshape(Image,1,[]));
end
% 将机场作为样本1,给出训练样本的标签Xlabel
XLable=ones(img_num,1);
phi1=[phi1 XLable];
%% 读取面包房的图片并处理
cd ([path,ObjDir2]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi2=zeros(img_num,64*64);

for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi2(pn,:)=double(reshape(Image,1,[]));
end
% 将面包房作为样本2,给出训练样本的标签Xlabel
XLable=2*ones(img_num,1);
phi2=[phi2 XLable];
%% 读取卧室的图片并处理
cd ([path1,ObjDir3]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi3=zeros(img_num,64*64);
for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi3
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi3(pn,:)=double(reshape(Image,1,[]));
end
% 将浴室作为样本3,给出训练样本的标签Xlabel
XLable=ones(img_num,1);
phi3=[phi3 XLable];
%% 读取浴室的图片并处理
cd ([path1,ObjDir4]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi4=zeros(img_num,64*64);
for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    % I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi4(pn,:)=double(reshape(Image,1,[]));
end
% 将卧室作为样本4,给出训练样本的标签Xlabel
XLable=zeros(img_num,1);
phi4=[phi4 XLable];
%% 列拼接四个矩阵并归一化
phi=[phi1;phi2;phi3;phi4];
% 矩阵归一化
phihead=phi(:,1:end-1);
[phihead,PS]=mapminmax(phihead); %[phi,PS]中phi为归一化后数值,PS为一种对应关系
% phi(1:end-1,:)为除标签栏(最后一列)之外归一化
phi=[phihead,phi(:,end)];
%% 留出法划分互斥的训练集和测试集
% 二维数组a次二划分
for i=1:a
    % 划分训练集和测试集比例(2:1划分)
    b=randperm(length(phi(:,1))); %打乱列序列
    e=round(length(phi(:,1))*2/3);
    c=b(1:e); %取打乱序列的前60%
    d=b(e+1:end); %取打乱序列的后40% %end直到数组结尾
    
    atrain=phi(c,:); %(:,:)为取原矩阵行和列,(:,1:50)为取原矩阵列,行取前60%
    atest=phi(d,:); %(:,d)为取原矩阵列,行取随机40%的行
    Xtrain{1,i}=atrain; %保存在train的(1,1)cell
    Xtest{1,i}=atest;
end
%% 保存a次二划分的数据集
save ('Xtrain.mat','Xtrain');
save ('Xtest.mat','Xtest');
save('A.mat','a');
% 读取a次二划分
clear;clc
load Xtrain.mat
load Xtest.mat
load A.mat
%% 夹角余弦和欧式距离判断测试集和哪个训练集最相似,然后把该训练集的标签给该测试集
for i=1:a % a为二划分次数
    % {}为元胞数组
    btrain=Xtrain{1,i}; %读取保存在train的(1,1)cell
    btest=Xtest{1,i};
    tempdis=-inf;tempj=0;
    Xlable{1,i}=zeros(1,size(btest,1));
    count=0; % 记录夹角余弦的错误个数
    flag=0; % 记录欧式距离的错误个数
    for j=1:size(btest,1) % 测试集的几行数据逐一进行比对
        test{1,j}=ones(size(btest,2),1); % size(A,2)得到A的列数
        test{1,j}=btest(j,:);
        Xlable{1,i}(j)=test{1,j}(1,end);  % 读取测试集标签
        for k=1:size(btrain,1) % 分别与训练集的几行数据一一比对
            train{1,k}=ones(size(btrain,2),1); 
            train{1,k}=btrain(k,:);
            res1=train{1,1}(1,end);
            res2=train{1,1}(1,end);
            % 计算两者之间的欧式距离
            distance1=sqrt(sum(abs(test{1,j}-train{1,k})).^2);  %sum(x.^2)计算数组的平方和
            if(distance1<tempdis)
                tempdis=distance1;tempj=k; % 如果距离最小则判断为同一类型
                res1=train{1,k}(1,end); % 将最短距离的训练集标签赋值给测试集
                % sprintf('res1为:%.2f',res1)
            end
            % 计算两者之间的夹角余弦
            B=[test{1,j};train{1,k}]; %将后续进行计算的两行代码放到一个矩阵
            distance=1-pdist(B,'cosine'); %计算夹角余弦
            if(distance>tempdis) %余弦值越接近1,两个向量越相似
                tempdis=distance;tempj=k; % 如果距离最大则判断为同一类型
                % test{1,j}(1,end)=train{1,k}(1,end); % 将夹角余弦最短的训练集标签赋值给测试集
                res2=train{1,k}(1,end);
            end
        end
        ress1(j)=res1;
        % 计算欧式距离的错误个数
        if(res1~=Xlable{1,i}(j))
            flag=flag+1;
        end
        ress2(j)=res2;
        % 计算夹角余弦的错误个数
        if(res2~=Xlable{1,i}(j))
            count=count+1;
        end
    end
    % 计算每个测试集的准确率 
    rateture(i)=1-flag/size(btest,1); % 欧式距离
    rateture2(i)=1-count/size(btest,1);  % 夹角余弦
    % sprintf('正确率为:%.2f',rateture)
end
%% 计算a次划分的准确率均值
meanture=mean(rateture(:));
meanture2=mean(rateture2(:));
sprintf('十次留出法划分得到 欧式距离的正确率为:%.2f    夹角余弦的正确率为:%.2f',meanture,meanture2)

实验五1.0版本(4)——交叉验证

% 1.将MIT室内场景数据库中机场、面包房、卧室、浴室作为四个类别。
% 利用交叉验证法完成训练集与测试集的划分(比例2:1),
% 并使用夹角余弦、距离进行多分类,给出分类准确率。
%% 设置参数
clc;clear;close all; 
path='D:\Desktop\大三上\神经网络\实验三\数据\MIT室内场景';
path1='D:\Desktop\大三上\神经网络\实验四\MIT室内场景2';
ObjDir1='\airport_inside';
ObjDir2='\bakery';
ObjDir3='\bathroom';
ObjDir4='\bedroom';
a=10; %留出法划分次数
b=10; %b折交叉验证
%% 读取指定路径下单个文件夹所有图像
%% 读取机场的图片并处理
cd ([path,ObjDir1]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi1=zeros(img_num,64*64);

for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi1
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi1(pn,:)=double(reshape(Image,1,[]));
end
% 将机场作为样本1,给出训练样本的标签Xlabel
XLable=ones(img_num,1);
phi1=[phi1 XLable];
%% 读取面包房的图片并处理
cd ([path,ObjDir2]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi2=zeros(img_num,64*64);

for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi2(pn,:)=double(reshape(Image,1,[]));
end
% 将面包房作为样本2,给出训练样本的标签Xlabel
XLable=2*ones(img_num,1);
phi2=[phi2 XLable];
%% 读取卧室的图片并处理
cd ([path1,ObjDir3]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi3=zeros(img_num,64*64);
for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi3
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi3(pn,:)=double(reshape(Image,1,[]));
end
% 将浴室作为样本3,给出训练样本的标签Xlabel
XLable=3*ones(img_num,1);
phi3=[phi3 XLable];
%% 读取浴室的图片并处理
cd ([path1,ObjDir4]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi4=zeros(img_num,64*64);
for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    % I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi4(pn,:)=double(reshape(Image,1,[]));
end
% 将卧室作为样本4,给出训练样本的标签Xlabel
XLable=4*ones(img_num,1);
phi4=[phi4 XLable];
%% 列拼接四个矩阵并归一化
phi=[phi1;phi2;phi3;phi4];
% % 矩阵归一化
% phihead=phi(:,1:end-1);
% [phihead,PS]=mapminmax(phihead); %[phi,PS]中phi为归一化后数值,PS为一种对应关系
% % phi(1:end-1,:)为除标签栏(最后一列)之外归一化
% phi=[phihead,phi(:,end)];
%% 交叉验证法划分互斥的训练集和测试集
% 二维数组a次b折交叉验证
for i=1:a
    % 参考函数crossvalind(https://ww2.mathworks.cn/help/bioinfo/ref/crossvalind.html)
     % meas和indices两个数据集,分别为原始的数据集和他们的标签。
     % 每一行是一个样本数据
     % 用交叉验证函数做b次交叉验证,将标签均分成b份,每一份打上不同的记号,记号为一个正整数
     % 得到样本被不同的数打标签,同样的数就是一份,一共是b份
     indices = crossvalind('Kfold',phi(:,end),b);
     % 对标签集进行分析,参考函数classperf(https://www.cnblogs.com/york-hust/p/3962270.html)
     % https://www.mathworks.com/help/bioinfo/ref/classperf.html
     cp = classperf(phi(:,end));
     for j=1:b
        %十次循环,每一次取其中一份作为测试集,其余的做训练集
        ctest = (indices == j);  % 获得test集元素在数据集中对应的单元编号
        ctrain = ~ctest;  % train集元素的编号为非test元素的编号
        % Xtrain{i,j}=ctrain; % 这个会造成Xtrain只有一列
        %保存在train的(1,1)cell
        Xtrain{i,j}=phi(ctrain,:); % 从数据集中划分出train样本的数据
        % Xtest{i,j}=ctest;
        Xtest{i,j}=phi(ctest,:);
    end
end
%% 保存a次二划分的数据集
save ('Xtrain.mat','Xtrain');
save ('Xtest.mat','Xtest');
save('A.mat','a');
save('B.mat','b');
% 读取a次二划分
clear;clc
load Xtrain.mat
load Xtest.mat
load A.mat
load B.mat
%% 夹角余弦和欧式距离判断测试集和哪个训练集最相似,然后把该训练集的标签给该测试集
for i=1:a % a为二划分次数
    for g=1:b
        % {}为元胞数组
        btrain=Xtrain{i,g}; %读取保存在train的(1,1)cell
        btest=Xtest{i,g};
        tempdis=-inf;tempj=0;
        Xlable{i,g}=zeros(1,size(btest,1));
        count=0; % 记录夹角余弦的错误个数
        flag=0; % 记录欧式距离的错误个数
        for j=1:size(btest,1) % 测试集的几行数据逐一进行比对
            test{1,j}=ones(size(btest,2),1); % size(A,2)得到A的列数
            test{1,j}=btest(j,:);
            Xlable{i,g}(j)=test{1,j}(1,end);  % 读取测试集标签
            for k=1:size(btrain,1) % 分别与训练集的几行数据一一比对
                train{1,k}=ones(size(btrain,2),1);
                train{1,k}=btrain(k,:);
                res1=train{1,1}(1,end);
                res2=train{1,1}(1,end);
                % 计算两者之间的欧式距离
                distance1=sqrt(sum(abs(test{1,j}-train{1,k})).^2);  %sum(x.^2)计算数组的平方和
                if(distance1<tempdis)
                    tempdis=distance1;tempj=k; % 如果距离最小则判断为同一类型
                    res1=train{1,k}(1,end); % 将最短距离的训练集标签赋值给测试集
                end
                % 计算两者之间的夹角余弦
                B=[test{1,j};train{1,k}]; %将后续进行计算的两行代码放到一个矩阵
                distance=1-pdist(B,'cosine'); %计算夹角余弦
                if(distance>tempdis) %余弦值越接近1,两个向量越相似
                    tempdis=distance;tempj=k; % 如果距离最大则判断为同一类型
                    % test{1,j}(1,end)=train{1,k}(1,end); % 将夹角余弦最短的训练集标签赋值给测试集
                    res2=train{1,k}(1,end);
                end
            end
            ress1(j)=res1;
            % 计算欧式距离的错误个数
            if(res1~=Xlable{i,g}(j))
                flag=flag+1;
            end
            ress2(j)=res2;
            % 计算夹角余弦的错误个数
            if(res2~=Xlable{i,g}(j))
                count=count+1;
            end
        end
        % 计算每个测试集的准确率
        rateture0(g)=1-flag/size(btest,1); % 欧式距离
        rateture02(g)=1-count/size(btest,1);  % 夹角余弦
        % sprintf('正确率为:%.2f',rateture)
    end
    rateture(i)=mean(rateture0(:));
    rateture2(i)=mean(rateture02(:));
end
%% 计算a次划分的准确率均值
meanture=mean(rateture(:));
meanture2=mean(rateture2(:));
sprintf('十次十折交换验证划分得到 欧式距离的正确率为:%.2f    夹角余弦的正确率为:%.2f',meanture,meanture2)

实验五1.0版本(5)——椒盐噪声

% 4.对训练集和测试集添加椒盐噪声,
% 记录当噪声密度d取0,0.01,0.05,0.1,0.2,0.5,0.8,1时的分类精度,
% 并画出精度曲线图,通过曲线图分析噪声对两种方法的影响。
%% 设置参数
clc;clear;close all; 
warning('off') %关掉警告
path='D:\Desktop\大三上\神经网络\实验三\数据\MIT室内场景';
path1='D:\Desktop\大三上\神经网络\实验四\MIT室内场景2';
ObjDir1='\airport_inside';
ObjDir2='\bakery';
ObjDir3='\bathroom';
ObjDir4='\bedroom';
a=1; %留出法划分次数
d0=[0.01 0.1 0.2 0.5 0.6 0.8 1]; %椒盐噪声
dture1=zeros(7,1);
dture2=zeros(7,1);
%% 读取指定路径下单个文件夹所有图像
%% 读取机场的图片并处理
cd ([path,ObjDir1]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi1=zeros(img_num,64*64);

for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi1
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi1(pn,:)=double(reshape(Image,1,[]));
end
% 将机场作为样本1,给出训练样本的标签Xlabel
XLable=ones(img_num,1);
phi1=[phi1 XLable];
%% 读取面包房的图片并处理
cd ([path,ObjDir2]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi2=zeros(img_num,64*64);

for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi2(pn,:)=double(reshape(Image,1,[]));
end
% 将面包房作为样本2,给出训练样本的标签Xlabel
XLable=2*ones(img_num,1);
phi2=[phi2 XLable];
%% 读取卧室的图片并处理
cd ([path1,ObjDir3]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi3=zeros(img_num,64*64);
for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi3
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi3(pn,:)=double(reshape(Image,1,[]));
end
% 将浴室作为样本3,给出训练样本的标签Xlabel
XLable=3*ones(img_num,1);
phi3=[phi3 XLable];
%% 读取浴室的图片并处理
cd ([path1,ObjDir4]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi4=zeros(img_num,64*64);
for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    % I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi4(pn,:)=double(reshape(Image,1,[]));
end
% 将卧室作为样本4,给出训练样本的标签Xlabel
XLable=4*ones(img_num,1);
phi4=[phi4 XLable];
%% 列拼接四个矩阵并保存
phi0=[phi1;phi2;phi3;phi4];
%% 7种椒盐噪声
for m=1:7 %注意是从1开始
    phi=phi0;
    noise=d0(m)
    %% 矩阵加入椒盐噪声并归一化
    % 矩阵归一化
    phihead=phi(:,1:end-1);
    phihead=imnoise(phihead,'salt & pepper',noise); %加入噪声密度:d的椒盐噪声
    % [phihead,PS]=mapminmax(phihead); %[phi,PS]中phi为归一化后数值,PS为一种对应关系
    % phi(1:end-1,:)为除标签栏(最后一列)之外归一化
    phi=[phihead,phi(:,end)];
    %% 留出法划分互斥的训练集和测试集
    % 二维数组a次二划分
    for i=1:a
        % 划分训练集和测试集比例(2:1划分)
        b=randperm(length(phi(:,1))); %打乱列序列
        e=round(length(phi(:,1))*2/3);
        c=b(1:e); %取打乱序列的前60%
        d=b(e+1:end); %取打乱序列的后40% %end直到数组结尾
        
        atrain=phi(c,:); %(:,:)为取原矩阵行和列,(:,1:50)为取原矩阵列,行取前60%
        atest=phi(d,:); %(:,d)为取原矩阵列,行取随机40%的行
        Xtrain{1,i}=atrain; %保存在train的(1,1)cell
        Xtest{1,i}=atest;
    end
    %% 夹角余弦和欧式距离判断测试集和哪个训练集最相似,然后把该训练集的标签给该测试集
    for i=1:a % a为二划分次数
        % {}为元胞数组
        btrain=Xtrain{1,i}; %读取保存在train的(1,1)cell
        btest=Xtest{1,i};
        tempdis1=inf;tempdis2=-inf;tempj1=0;tempj2=0;
        Xlable{1,i}=zeros(1,size(btest,1));
        count=0; % 记录夹角余弦的错误个数
        flag=0; % 记录欧式距离的错误个数
        for j=1:size(btest,1) % 测试集的几行数据逐一进行比对
            test{1,j}=ones(size(btest,2),1); % size(A,2)得到A的列数
            test{1,j}=btest(j,:);
            Xlable{1,i}(j)=test{1,j}(1,end);  % 读取测试集标签
            for k=1:size(btrain,1) % 分别与训练集的几行数据一一比对
                train{1,k}=ones(size(btrain,2),1);
                train{1,k}=btrain(k,:);
                res1=train{1,1}(1,end);
                res2=train{1,1}(1,end);
                % 计算两者之间的欧式距离
                distance1=sqrt(sum(abs(test{1,j}-train{1,k})).^2);  %sum(x.^2)计算数组的平方和
                if(distance1<tempdis1)
                    tempdis1=distance1;tempj1=k; % 如果距离最小则判断为同一类型
                    res1=train{1,tempj1}(1,end); % 将最短距离的训练集标签赋值给测试集
                    % sprintf('res1为:%.2f',res1)
                end
                % 计算两者之间的夹角余弦
                B=[test{1,j};train{1,k}]; %将后续进行计算的两行代码放到一个矩阵
                distance=1-pdist(B,'cosine'); %计算夹角余弦
                if(distance>tempdis2) %余弦值越接近1,两个向量越相似
                    tempdis2=distance;tempj2=k; % 如果距离最大则判断为同一类型
                    % test{1,j}(1,end)=train{1,k}(1,end); % 将夹角余弦最短的训练集标签赋值给测试集
                    res2=train{1,k}(1,end);
                end
            end
            ress1(j)=res1;
            % 计算欧式距离的错误个数
            if(res1~=Xlable{1,i}(j))
                flag=flag+1;
            end
            ress2(j)=res2;
            % 计算夹角余弦的错误个数
            if(res2~=Xlable{1,i}(j))
                count=count+1;
            end
        end
        % 计算每个测试集的准确率
        rateture(i)=1-flag/size(btest,1); % 欧式距离
        rateture2(i)=1-count/size(btest,1);  % 夹角余弦
        % sprintf('正确率为:%.2f',rateture)
    end
    %% 计算a次划分的准确率均值
    %% 计算当噪声密度d取0,0.01,0.05,0.1,0.2,0.5,0.8,1时的分类精度
    meanture=mean(rateture(:));
    meanture2=mean(rateture2(:));
    sprintf('当噪声密度为%.2f时,十次留出法划分得到 欧式距离的正确率为:%.2f    夹角余弦的正确率为:%.2f\n',noise,meanture,meanture2)
    dture1(m)=meanture;
    dture2(m)=meanture2;
end
%% 画出精度曲线图,通过曲线图分析噪声对两种方法的影响
x = d;y1 = dture1;y2 = dture2;
% x = [0.01 0.1 0.2 0.5 0.6 0.8 1];y1 = [98 97 87 86 88 91 94];
% y2 = [95 95 95 95 95 95 95];
% 新建图画,若figure(1)即指定图画句柄1
f1 = figure(1);
% 设置布画大小,合适的大小可防止粘贴到word文档时图片模糊
set(gcf,'unit','centimeters','position',[10 5 14 7]);
% 设置布画背景色
set(gcf,'Color',[0.9 0.9 0.9]);
plot(x,y1,'--ob')
hold on
plot(x,y2,':*g')
axis([0 1 0 100])
% 设置坐标格
grid on;
% 批量设置曲线粗细
set(findobj(get(gca,'Children'),'LineWidth',0.5),'LineWidth',2);
set(gca,'XTick', [0.01 0.1 0.2 0.5 0.6 0.8 1]);
set(gca,'XTickLabel',{'0.01','0.1','0.2','0.5','0.6','0.8','1'});
% 设置字体格式
set(gca,'FontSize',15); xlabel('噪声密度','fontsize',17);
ylabel('分类精度','fontsize',17);
legend('欧氏距离','夹角余弦')
title('精度曲线图'); 

实验五1.0版本(6)——仅测试集椒盐噪声

% 3.对测试集添加椒盐噪声,
% 记录当噪声密度d取0,0.01,0.05,0.1,0.2,0.5,0.8,1时的分类精度,
% 并画出精度曲线图,通过曲线图分析噪声对两种方法的影响。
%% 设置参数
clc;clear;close all; 
warning('off') %关掉警告
path='D:\Desktop\大三上\神经网络\实验三\数据\MIT室内场景';
path1='D:\Desktop\大三上\神经网络\实验四\MIT室内场景2';
ObjDir1='\airport_inside';
ObjDir2='\bakery';
ObjDir3='\bathroom';
ObjDir4='\bedroom';
a=10; %留出法划分次数
d0=[0.01 0.1 0.2 0.5 0.6 0.8 1]; %椒盐噪声
dture1=zeros(7,1);
dture2=zeros(7,1);
%% 读取指定路径下单个文件夹所有图像
%% 读取机场的图片并处理
cd ([path,ObjDir1]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi1=zeros(img_num,64*64);

for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi1
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi1(pn,:)=double(reshape(Image,1,[]));
end
% 将机场作为样本1,给出训练样本的标签Xlabel
XLable=ones(img_num,1);
phi1=[phi1 XLable];
%% 读取面包房的图片并处理
cd ([path,ObjDir2]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi2=zeros(img_num,64*64);

for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi2(pn,:)=double(reshape(Image,1,[]));
end
% 将面包房作为样本2,给出训练样本的标签Xlabel
XLable=2*ones(img_num,1);
phi2=[phi2 XLable];
%% 读取卧室的图片并处理
cd ([path1,ObjDir3]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi3=zeros(img_num,64*64);
for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi3
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    I1=rgb2gray(img_origin); % RGB图像转灰度图像
    Image=imresize(I1,[64,64]);
    phi3(pn,:)=double(reshape(Image,1,[]));
end
% 将浴室作为样本3,给出训练样本的标签Xlabel
XLable=3*ones(img_num,1);
phi3=[phi3 XLable];
%% 读取浴室的图片并处理
cd ([path1,ObjDir4]); %切换到指定路径下 
allfigs=struct2cell(dir('*.jpg')); %只处理jpg文件 
[w,img_num]=size(allfigs); %获得文件的个数 
phi4=zeros(img_num,64*64);
for pn=1:img_num %逐次取出图片 % 将图像数据保存于phi
    image_name=allfigs{1,pn}; %allfigs{1,pn}存储每个图片的名字 
    img_origin=imread(image_name); %读取图片
    if(ndims(img_origin)==3)
        I1=rgb2gray(img_origin); % RGB图像转灰度图像
    end
    Image=imresize(I1,[64,64]);
    phi4(pn,:)=double(reshape(Image,1,[]));
end
% 将卧室作为样本4,给出训练样本的标签Xlabel
XLable=4*ones(img_num,1);
phi4=[phi4 XLable];
%% 列拼接四个矩阵并保存
phi0=[phi1;phi2;phi3;phi4];
%% 7种椒盐噪声
for m=1:7 %注意是从1开始
    phi=phi0;
    noise=d0(m)
    %% 留出法划分互斥的训练集和测试集
    % 二维数组a次二划分
    for i=1:a
        % 划分训练集和测试集比例(2:1划分)
        b=randperm(length(phi(:,1))); %打乱列序列
        e=round(length(phi(:,1))*2/3);
        c=b(1:e); %取打乱序列的前60%
        d=b(e+1:end); %取打乱序列的后40% %end直到数组结尾
        
        % 划分
        atrain0=phi(c,:); %(:,:)为取原矩阵行和列,(:,1:50)为取原矩阵列,行取前60%
        phihead0=atrain0(:,1:end-1);
        % 加入椒盐噪声
        phihead0=imnoise(phihead0,'salt & pepper',noise); %加入噪声密度:d的椒盐噪声
        phi(c,1:end-1)=phihead0;
        % 归一化
%         phihead=phi(:,1:end-1);
%         [phihead,PS]=mapminmax(phihead); %[phi,PS]中phi为归一化后数值,PS为一种对应关系
%         % phi(1:nd-1,:)为除标签栏(最后一列)之外归一化
        
        atest=phi(d,:); %(:,d)为取原矩阵列,行取随机40%的行
        atrain=phi(c,:);
        Xtrain{1,i}=atrain; %保存在train的(1,1)cell
        Xtest{1,i}=atest;
    end
    %% 夹角余弦和欧式距离判断测试集和哪个训练集最相似,然后把该训练集的标签给该测试集
    for i=1:a % a为二划分次数
        % {}为元胞数组
        btrain=Xtrain{1,i}; %读取保存在train的(1,1)cell
        btest=Xtest{1,i};
        tempdis1=-inf;tempdis2=-inf;tempj1=0;tempj2=0;
        Xlable{1,i}=zeros(1,size(btest,1));
        count=0; % 记录夹角余弦的错误个数
        flag=0; % 记录欧式距离的错误个数
        for j=1:size(btest,1) % 测试集的几行数据逐一进行比对
            test{1,j}=ones(size(btest,2),1); % size(A,2)得到A的列数
            test{1,j}=btest(j,:);
            Xlable{1,i}(j)=test{1,j}(1,end);  % 读取测试集标签
            for k=1:size(btrain,1) % 分别与训练集的几行数据一一比对
                train{1,k}=ones(size(btrain,2),1);
                train{1,k}=btrain(k,:);
                res1=train{1,1}(1,end);
                res2=train{1,1}(1,end);
                % 计算两者之间的欧式距离
                distance1=sqrt(sum(abs(test{1,j}-train{1,k})).^2);  %sum(x.^2)计算数组的平方和
                if(distance1<tempdis1)
                    tempdis1=distance1;tempj1=k; % 如果距离最小则判断为同一类型
                    res1=train{1,k}(1,end); % 将最短距离的训练集标签赋值给测试集
                    % sprintf('res1为:%.2f',res1)
                end
                % 计算两者之间的夹角余弦
                B=[test{1,j};train{1,k}]; %将后续进行计算的两行代码放到一个矩阵
                distance=1-pdist(B,'cosine'); %计算夹角余弦
                if(distance>tempdis2) %余弦值越接近1,两个向量越相似
                    tempdis2=distance;tempj2=k; % 如果距离最大则判断为同一类型
                    % test{1,j}(1,end)=train{1,k}(1,end); % 将夹角余弦最短的训练集标签赋值给测试集
                    res2=train{1,k}(1,end);
                end
            end
            ress1(j)=res1;
            % 计算欧式距离的错误个数
            if(res1~=Xlable{1,i}(j))
                flag=flag+1;
            end
            ress2(j)=res2;
            % 计算夹角余弦的错误个数
            if(res2~=Xlable{1,i}(j))
                count=count+1;
            end
        end
        % 计算每个测试集的准确率
        rateture(i)=1-flag/size(btest,1); % 欧式距离
        ratetre2(i)=1-count/size(btest,1);  % 夹角余弦
        % sprintf('正确率为:%.2f',rateture)
    end
    %% 计算a次划分的准确率均值
    %% 计算当噪声密度d取0,0.01,0.05,0.1,0.2,0.5,0.8,1时的分类精度
    meanture=mean(rateture(:));
    meanture2=mean(rateture2(:));
    sprintf('当噪声密度为%.2f时,十次留出法划分得到 欧式距离的正确率为:%.2f    夹角余弦的正确率为:%.2f\n',noise,meanture,meanture2)
    dture1(m)=meanture;
    dture2(m)=meanture2;
end
%% 画出精度曲线图,通过曲线图分析噪声对两种方法的影响
x = d0;y1 = dture1;y2 = dture2;
% x = [0.01 0.1 0.2 0.5 0.6 0.8 1];y1 = [98 97 87 86 88 91 94];
% y2 = [95 95 95 95 95 95 95];
% 新建图画,若figure(1)即指定图画句柄1
f1 = figure(1);
% 设置布画大小,合适的大小可防止粘贴到word文档时图片模糊
set(gcf,'unit','centimeters','position',[10 5 14 7]);
% 设置布画背景色
set(gcf,'Color',[0.9 0.9 0.9]);
plot(d0,y1,'--ob')
hold on
plot(d0,y2,':*g')
axis([0 1 0 1])
% 设置坐标格
grid on;
% 批量设置曲线粗细
set(findobj(get(gca,'Children'),'LineWidth',0.5),'LineWidth',2);
set(gca,'XTick', [0.01 0.1 0.2 0.5 0.6 0.8 1]);
set(gca,'XTickLabel',{'0.01','0.1','0.2','0.5','0.6','0.8','1'});
% 设置字体格式
set(gca,'FontSize',15); xlabel('噪声密度','fontsize',17);
ylabel('分类精度','fontsize',17);
legend('欧氏距离','夹角余弦')
title('精度曲线图'); 

实验五2.0改进版(6)——仅测试集椒盐噪声

% ##改进版## 3.对测试集添加椒盐噪声,
% 记录当噪声密度d取0,0.01,0.05,0.1,0.2,0.5,0.8,1时的分类精度,
% 并画出精度曲线图,通过曲线图分析噪声对两种方法的影响。
%% 设置参数
clc;clear;close all;
warning('off') %关掉警告
base_path = 'D:\Desktop\大三上\神经网络\数据\MIT室内场景';
path = string();
subpath = dir( base_path );
a=10; %留出法次数
%% 读取指定路径单文件夹下,all文件夹内的all图像
all_imgnum=0;all_e=0;all_f=0;
for i = 1:length(subpath)-2 % 读取单文件夹下,all文件夹% 1,2分别是.和..% 先获取第一个子文件路径,然后获取第二个子文件路径
    sub_path = fullfile(base_path, subpath(i+2).name);% disp(sub_path); % D:\Desktop\大三上\神经网络\数据\MIT室内场景\airport_inside
    image_name = dir(sub_path); % 获取文件夹里的所有图像信息% disp(image_name(3).name); % airport_inside_0001.jpg
    img_num=length(image_name)-2; % 文件夹里图像个数% disp(img_num); % 608 405 197 662
    all_imgnum=all_imgnum+img_num;% disp(all_imgnum); % 608 1013 1210 1872
    e=round(img_num*2/3); % 留出法划分比例
    f=img_num-e;
    all_e=all_e+e;
    all_f=all_f+f;
    %% 获取图片数据
    for j = 1:img_num % 获取子文件夹下图片的路径
        % fullfile函数利用文件各部分信息创建并合成完整文件名
        img_path = fullfile(sub_path, image_name(j+2).name); % 子文件夹+图片名称
        read_img = imread(img_path); % 读图
        if(ndims(read_img)==3)
            read_img = rgb2gray(read_img);  % RGB图像转灰度图像
        end
        image = imresize(read_img, [64,64]);  % 图片统一大小,指定长宽[64,64]
        phi_cell{1,all_imgnum-img_num+j}=image;  % 存放每个图片data于元胞数组phi_cell,一个元胞存放一个图像
    end
    %% 留出法a次二划分互斥的训练集和测试集 数据
    for k=1:a
        % 划分训练集和测试集比例(2:1划分)
        num=randperm(img_num); %打乱列序列
        train_num=num(1:e); %取打乱序列的前60%
        test_num=num(e+1:end); %取打乱序列的后40% %end直到数组结尾
        % 划分数据
        for ai=1:length(train_num)
            Xtrain{all_e-e+ai,k}=phi_cell{1,all_imgnum-img_num+train_num(ai)};%Xtrain{k,:}第k次留出法的训练集
        end
        for bi=1:length(test_num)
            Xtest{all_f-f+bi,k}=phi_cell{1,all_imgnum-img_num+test_num(bi)};
        end
    end
    %% 存放图片label于矩阵phi_label % 定义标签,1:机场;2:面包房;3:bathroom;4:bedrood
    % phi_label(1,all_imgnum-img_num+1:all_imgnum)=label*ones(1,img_num);% 行拼接每个标签给对应的图片个数拼成一行
    % Ltrain=phi_label(1,train_num);
    Ltrain(1,all_e-e+1:all_e)=i*ones(1,e);% 行拼接每个标签给对应的图片个数拼成一行
    Ltest(1,all_f-f+1:all_f)=i*ones(1,f);
end
%% 7种椒盐噪声
d0=[0.01 0.1 0.2 0.5 0.6 0.8 1]; %椒盐噪声
size_d0=size(d0);
b=size(Xtest); %625    10
b0=size(Xtrain);
noise_Xtest=cell(size_d0(2),b(2));
Xtrain1=cell(1,b0(2));
for m=1:size_d0(2) %注意是从1开始
    noise=d0(m);
    %% 对测试集图片加入椒盐噪声
    for a = 1:b(2)
        for c = 1:b(1)
            img = Xtest{c,a};
            img2 = imnoise(img,'salt & pepper',noise);
            phi0(c,:)=double(reshape(img2,1,[]));
        end
        for d = 1:b0(1)
            img1=Xtrain{d,a};
            phi1(d,:)=double(reshape(img1,1,[]));
        end
        noise_Xtest{m,a}=phi0;
        Xtrain1{1,a}=phi1;
    end
end
%% 保存划分后的数据集
save('Xtrain1.mat','Xtrain1'); % 存数据
save ('noise_Xtest.mat','noise_Xtest');
save('Ltrain.mat','Ltrain');% 存标签
save('Ltest.mat','Ltest');
%% 读取数据集
%clear;clc
load Xtrain1.mat
load noise_Xtest.mat
load Ltrain.mat
load Ltest.mat
%% 夹角余弦和欧式距离判断测试集和哪个训练集最相似,然后把该训练集的标签给该测试集
d0=[0.01 0.1 0.2 0.5 0.6 0.8 1];
size_d0=size(d0);
% rateture0 = zeros(1,b(2));rateture1 = zeros(1,b(2));
meanture0=zeros(1,size_d0(2));meanture1=zeros(1,size_d0(2));
for m=1:size_d0(2) % 7种噪声
    noise=d0(m)
    for a = 1:b(2) % 10次划分
        res = ones(1,length(Ltest)); % 保存预测值
        for k = 1:length(Ltest) % 对每一个测试集,计算内积(夹角余弦)
            test_d = noise_Xtest{m,a}(k,:);  % 提取测试数据
            tmp_res0 = ones(length(Ltrain),1);  % 临时保存一个测试对应的所有的训练的夹角余弦
            tmp_res1 = ones(length(Ltrain),1);  % 欧氏距离
            for p = 1:length(Ltrain)
                train_d = Xtrain1{1,a}(p,:); % 提取训练数据
                tmp_res0(p)= sqrt(sum(abs(train_d-test_d)).^2);  %sum(x.^2)计算数组的平方和
                tmp_res1(p)= sum(train_d.*test_d)/norm(test_d)/norm(train_d); % 求夹角余弦
            end
            [n0,index0] = max(tmp_res0);
            [n1,index1] = max(tmp_res1);
            res0(k) = Ltrain(index0);  % 将每一个测试集预测的结果保存在res里
            res1(k) = Ltrain(index1);
        end
        % 求正确率、错误率
        count = 0;flag = 1;
        for i = 1:length(res0)
            if( res0(i)==Ltest(i) )
                count = count + 1;
            end
            if( res1(i)==Ltest(i) )
                flag = flag + 1;
            end
        end
        % 计算每个测试集的准确率
        rateture0(a) = count/length(res0);% 欧式距离
        rateture1(a) = flag/length(res1);% 夹角余弦
    end
    %% 计算当噪声密度d取0,0.01,0.05,0.1,0.2,0.5,0.8,1时的分类精度
    meanture0(m) = mean(rateture0(:)) * 100;
    meanture1(m) = mean(rateture1(:)) * 100;
    sprintf('当噪声密度为%.2f时,十次留出法划分得到 欧式距离的正确率为:%.2f    夹角余弦的正确率为:%.2f\n',noise,meanture0(m),meanture1(m))
end
%% 画出精度曲线图,通过曲线图分析噪声对两种方法的影响
x = d0;y1 = meanture0;y2 = meanture1;
% x = [0.01 0.1 0.2 0.5 0.6 0.8 1];y1 = [98 97 87 86 88 91 94];
% y2 = [95 95 95 95 95 95 95];
% 新建图画,若figure(1)即指定图画句柄1
f1 = figure(1);
% 设置布画大小,合适的大小可防止粘贴到word文档时图片模糊
set(gcf,'unit','centimeters','position',[10 5 14 7]);
% 设置布画背景色
set(gcf,'Color',[0.9 0.9 0.9]);
plot(x,y1,'--ob')
hold on
plot(x,y2,':*g')
axis([0 1 0 1])
% 设置坐标格
grid on;
% 批量设置曲线粗细
set(findobj(get(gca,'Children'),'LineWidth',0.5),'LineWidth',2);
set(gca,'XTick', [0.01 0.1 0.2 0.5 0.6 0.8 1]);
set(gca,'XTickLabel',{'0.01','0.1','0.2','0.5','0.6','0.8','1'});
% 设置字体格式
set(gca,'FontSize',15); xlabel('噪声密度','fontsize',17);
ylabel('分类精度','fontsize',17);
legend('欧氏距离','夹角余弦')
title('精度曲线图');

实验五2.0改进版(5)——椒盐噪声

% ##改进版## 4.对训练集和测试集添加椒盐噪声,
% 记录当噪声密度d取0,0.01,0.05,0.1,0.2,0.5,0.8,1时的分类精度,
% 并画出精度曲线图,通过曲线图分析噪声对两种方法的影响。
%% 设置参数
clc;clear;close all;
warning('off') %关掉警告
base_path = 'D:\Desktop\大三上\神经网络\数据\MIT室内场景';
path = string();
subpath = dir( base_path );
a=10; %留出法次数
%% 读取指定路径单文件夹下,all文件夹内的all图像
all_imgnum=0;all_e=0;all_f=0;
for i = 1:length(subpath)-2 % 读取单文件夹下,all文件夹% 1,2分别是.和..% 先获取第一个子文件路径,然后获取第二个子文件路径
    sub_path = fullfile(base_path, subpath(i+2).name);% disp(sub_path); % D:\Desktop\大三上\神经网络\数据\MIT室内场景\airport_inside
    image_name = dir(sub_path); % 获取文件夹里的所有图像信息% disp(image_name(3).name); % airport_inside_0001.jpg
    img_num=length(image_name)-2; % 文件夹里图像个数% disp(img_num); % 608 405 197 662
    all_imgnum=all_imgnum+img_num;% disp(all_imgnum); % 608 1013 1210 1872
    e=round(img_num*2/3); % 留出法划分比例
    f=img_num-e;
    all_e=all_e+e;
    all_f=all_f+f;
    %% 获取图片数据
    for j = 1:img_num % 获取子文件夹下图片的路径
        % fullfile函数利用文件各部分信息创建并合成完整文件名
        img_path = fullfile(sub_path, image_name(j+2).name); % 子文件夹+图片名称
        read_img = imread(img_path); % 读图
        if(ndims(read_img)==3)
            read_img = rgb2gray(read_img);  % RGB图像转灰度图像
        end
        image = imresize(read_img, [64,64]);  % 图片统一大小,指定长宽[64,64]
        phi_cell{1,all_imgnum-img_num+j}=image;  % 存放每个图片data于元胞数组phi_cell,一个元胞存放一个图像
    end
    %% 留出法a次二划分互斥的训练集和测试集 数据
    for k=1:a
        % 划分训练集和测试集比例(2:1划分)
        num=randperm(img_num); %打乱列序列
        train_num=num(1:e); %取打乱序列的前60%
        test_num=num(e+1:end); %取打乱序列的后40% %end直到数组结尾
        % 划分数据
        for ai=1:length(train_num)
            Xtrain{all_e-e+ai,k}=phi_cell{1,all_imgnum-img_num+train_num(ai)};%Xtrain{k,:}第k次留出法的训练集
        end
        for bi=1:length(test_num)
            Xtest{all_f-f+bi,k}=phi_cell{1,all_imgnum-img_num+test_num(bi)};
        end
    end
    %% 存放图片label于矩阵phi_label % 定义标签,1:机场;2:面包房;3:bathroom;4:bedrood
    % phi_label(1,all_imgnum-img_num+1:all_imgnum)=label*ones(1,img_num);% 行拼接每个标签给对应的图片个数拼成一行
    % Ltrain=phi_label(1,train_num);
    Ltrain(1,all_e-e+1:all_e)=i*ones(1,e);% 行拼接每个标签给对应的图片个数拼成一行
    Ltest(1,all_f-f+1:all_f)=i*ones(1,f);
end
%% 7种椒盐噪声
d0=[0.01 0.1 0.2 0.5 0.6 0.8 1]; %椒盐噪声
size_d0=size(d0);
b=size(Xtest); %625    10
b0=size(Xtrain);
noise_Xtest=cell(size_d0(2),b(2));
noise_Xtrain=cell(size_d0(2),b0(2));
for m=1:size_d0(2) %注意是从1开始
    noise=d0(m);
    %% 对测试集图片加入椒盐噪声
    for a = 1:b(2)
        for c = 1:b(1)
            img = Xtest{c,a};
            img2 = imnoise(img,'salt & pepper',noise);
            phi0(c,:)=double(reshape(img2,1,[]));
        end
        for d = 1:b0(1)
            img1=Xtrain{d,a};
            img3 = imnoise(img1,'salt & pepper',noise);
            phi1(d,:)=double(reshape(img3,1,[]));
        end
        noise_Xtest{m,a}=phi0;
        noise_Xtrain{m,a}=phi1;
    end
end
%% 保存划分后的数据集
save('noise_Xtrain.mat','noise_Xtrain'); % 存数据
save ('noise_Xtest.mat','noise_Xtest');
save('Ltrain.mat','Ltrain');% 存标签
save('Ltest.mat','Ltest');
%% 读取数据集
%clear;clc
load noise_Xtrain.mat
load noise_Xtest.mat
load Ltrain.mat
load Ltest.mat
%% 夹角余弦和欧式距离判断测试集和哪个训练集最相似,然后把该训练集的标签给该测试集
d0=[0.01 0.1 0.2 0.5 0.6 0.8 1];
size_d0=size(d0);
% rateture0 = zeros(1,b(2));rateture1 = zeros(1,b(2));
meanture0=zeros(1,size_d0(2));meanture1=zeros(1,size_d0(2));
for m=1:size_d0(2) % 7种噪声
    noise=d0(m)
    for a = 1:b(2) % 10次划分
        res = ones(1,length(Ltest)); % 保存预测值
        for k = 1:length(Ltest) % 对每一个测试集,计算内积(夹角余弦)
            test_d = noise_Xtest{m,a}(k,:);  % 提取测试数据
            tmp_res0 = ones(length(Ltrain),1);  % 临时保存一个测试对应的所有的训练的夹角余弦
            tmp_res1 = ones(length(Ltrain),1);  % 欧氏距离
            for p = 1:length(Ltrain)
                train_d = noise_Xtrain{m,a}(p,:); % 提取训练数据
                tmp_res0(p)= sqrt(sum(abs(train_d-test_d)).^2);  %sum(x.^2)计算数组的平方和
                tmp_res1(p)= sum(train_d.*test_d)/norm(test_d)/norm(train_d); % 求夹角余弦
            end
            [n0,index0] = max(tmp_res0);
            [n1,index1] = max(tmp_res1);
            res0(k) = Ltrain(index0);  % 将每一个测试集预测的结果保存在res里
            res1(k) = Ltrain(index1);
        end
        % 求正确率、错误率
        count = 0;flag = 1;
        for i = 1:length(res0)
            if( res0(i)==Ltest(i) )
                count = count + 1;
            end
            if( res1(i)==Ltest(i) )
                flag = flag + 1;
            end
        end
        % 计算每个测试集的准确率
        rateture0(a) = count/length(res0);% 欧式距离
        rateture1(a) = flag/length(res1);% 夹角余弦
    end
    %% 计算当噪声密度d取0,0.01,0.05,0.1,0.2,0.5,0.8,1时的分类精度
    meanture0(m) = mean(rateture0(:)) * 100;
    meanture1(m) = mean(rateture1(:)) * 100;
    sprintf('当噪声密度为%.2f时,十次留出法划分得到 欧式距离的正确率为:%.2f    夹角余弦的正确率为:%.2f\n',noise,meanture0(m),meanture1(m))
end
%% 画出精度曲线图,通过曲线图分析噪声对两种方法的影响
x = d0;y1 = meanture0;y2 = meanture1;
% x = [0.01 0.1 0.2 0.5 0.6 0.8 1];y1 = [98 97 87 86 88 91 94];
% y2 = [95 95 95 95 95 95 95];
% 新建图画,若figure(1)即指定图画句柄1
f1 = figure(1);
% 设置布画大小,合适的大小可防止粘贴到word文档时图片模糊
set(gcf,'unit','centimeters','position',[10 5 14 7]);
% 设置布画背景色
set(gcf,'Color',[0.9 0.9 0.9]);
plot(x,y1,'--ob')
hold on
plot(x,y2,':*g')
axis([0 1 0 1])
% 设置坐标格
grid on;
% 批量设置曲线粗细
set(findobj(get(gca,'Children'),'LineWidth',0.5),'LineWidth',2);
set(gca,'XTick', [0.01 0.1 0.2 0.5 0.6 0.8 1]);
set(gca,'XTickLabel',{'0.01','0.1','0.2','0.5','0.6','0.8','1'});
% 设置字体格式
set(gca,'FontSize',15); xlabel('噪声密度','fontsize',17);
ylabel('分类精度','fontsize',17);
legend('欧氏距离','夹角余弦')
title('精度曲线图');
举报

相关推荐

0 条评论