间距可视化
我们以resnet50进行举例,最后一个特征层维度是20481(在这里我们忽略batch,每一个样本都是独立的),假设有n个样本,我们将这里的特征导出,可以得到大小是n2048的矩阵。
首先,对提取到的特征数据进行标准化,matlab代码如下:
function [ Dnorm ]= normalizeBase(D)
%% Normalize dictionary to have unit l2-norm
norms = sqrt(sum(D.^2));
[m,n]=size(D);
for i=1:n
Dnorm(:,i) = D(:,i)/norms(1,i);
end
return;
通过欧氏距离的公式,我们对样本间距进行计算,欧氏距离的matlab代码如下:
function D = EuclidDist(galX, probX)
D = bsxfun(@plus, sum(galX.^2, 2), sum(probX.^2, 2)') - 2 * galX * probX';
end
利用上面两个基础的代码我们完成如下操作:
filename = "yourdata_path.csv";
labelfilename = yourdata_path.csv";
data = readtable(filename);
dataMatrix = table2array(data);
data1 =dataMatrix(1:10121,:);
data2 = dataMatrix(10122:end,:);
data1 = data1';
data2 = data2';
data1 = normalizeBase(data1);
data2 = normalizeBase(data2);
dist =EuclidDist(data1',data2');
这里的dist就是我们欧氏距离计算的结果。
labelfilename应该是你的数据的索引,在这里我们使用labeldata 作为类别标签,而后使用两个循环对数据进行遍历,在这里我们是有两个模态的数据需要进行计算,所以我们需要得到的是在两个模态下样本的欧氏距离的数据,所以下面的A和B可以理解为类内距离和类间距离。
% C = cov(dataMatrix);
euclideanDistances = dist;
%euclideanDistances = pdist2(data1, data2,"mahalanobis");
%euclideanDistances = pdist2(data1, data2,"mahal");
%outputFilename = 'C:\Users\Desktop\featuredistance\our\featuredistance.csv';
%writematrix(euclideanDistances, outputFilename);
% euclideanDistances = normalize(euclideanDistances);
labeldata = readtable(labelfilename);
%labels1 = labeldata{ 1:10121,1 };
%labels2 = labeldata{10122:end, 1};
% 使用labeldata作为类别标签列
ed = euclideanDistances;
label_column = table2array (labeldata);
label_column1 = label_column(1:10121);
label_column2 = label_column(10122:end);
A=zeros(length(label_column1),length(label_column2));
for i = 1: 1: length(label_column1)
for j = 1: 1: length(label_column2)
if label_column1(i) == label_column2(j)
A(i,j) = ed(i,j);
end
end
end
B=zeros(length(label_column1),length(label_column2));
for i = 1: 1: length(label_column1)
for j = 1: 1: length(label_column2)
if label_column1(i) ~= label_column2(j)
B(i,j) = ed(i,j);
end
end
end
于是我们得到了矩阵A和B,为了计算方便,直接拉伸为一维的数据结果(下方的C和D),然后画出频次图。
C = A(:);
D = B(:);
C(C==0)=[];
D(D==0)=[];
C = C.*4;
D = D.*4;
% 假设变量 C 和 D 包含两个分布的数据...
% 画第一个直方图
figure;
subplot(1,2,1)
totalItemsC = numel(C); % 计算C的总元素数
totalItemsD = numel(D); % 计算D的总元素数
% 画第一个直方图
h1 = histogram(C, 'BinWidth', 0.005, 'Normalization', 'probability', 'FaceColor', 'blue', 'FaceAlpha', 0.5, 'EdgeColor', 'none');
hold on; % 保持当前图像,以便在相同的坐标轴上绘制第二个直方图
xlim([0 1])
% 画第二个直方图
h2 = histogram(D, 'BinWidth', 0.005, 'Normalization', 'probability', 'FaceColor', 'green', 'FaceAlpha', 0.5, 'EdgeColor', 'none');
yticks([0 0.008 0.016 0.024 0.032 0.040]);
yticklabels({'0', '1', '2', '3', '4'});
xticks([ 0 0.2 0.4 0.6 0.8 1.0]);
xticklabels({'0', '0.2','0.4', '0.6', '0.8', '1.0'});
% 计算两个分布的峰值位置
peakC = mean(C); % 你也可以选择 mean(C) 如果你的数据分布比较对称
peakD = mean(D); % 同上
yLimits =0.8* get(gca, 'YLim');
line([peakC peakC], yLimits, 'Color', 'black', 'LineWidth', 1);
line([peakD peakD], yLimits, 'Color', 'black', 'LineWidth', 1);
x_start = peakC;
x_end = peakC + 0.4*(peakD-peakC);
y_constant = 0.013;
line([x_start x_end], [y_constant y_constant], 'Color', 'black', 'LineWidth', 1);
x_start = peakC + 0.6*(peakD-peakC);
x_end = peakD;
line([x_start x_end], [y_constant y_constant], 'Color', 'black', 'LineWidth', 1);
text(peakC + 0.53*(peakD-peakC), y_constant, '\delta_1', 'HorizontalAlignment', 'center', 'Color', 'k', 'FontSize', 17,'VerticalAlignment', 'middle');
% 设置图例和标题等
%legend(' intra-class', 'inter-class');
%title('两个分布的直方图');
xlabel('Baseline');
ylabel('Frequency');
%hold off; % 结束绘图
你可能需要根据你的图像信息对你的这些图像参数进行调整,以便于得到你想要的结果。
文章介绍了如何使用ResNet50模型的特征向量进行标准化处理,计算样本间的欧氏距离,并通过实例展示了如何将这些距离转化为类别内和类别间的直方图,用于分析和可视化数据分布。

1499

被折叠的 条评论
为什么被折叠?



