9月28日计算机视觉基础学习笔记——卷积神经网络


前言

本文为9月28日计算机视觉基础学习笔记——卷积神经网络,分为三个章节:

  • Week 5 homework——K++ means;
  • 图像滤波;
  • CNN。

一、Week 5 homework——K++ means

# coding:utf-8
# KMeans
# step1:随机设定初始聚类中心
# step2:将距离某个聚类中心距离近的样本点归类到该聚类中心,将样本全部归类完毕后得到多个簇
# step3:计算每个簇的均值作为新的聚类中心
# step4:重复第二步和第三步直至聚类中心不再发生变化

# KMeans++
# step1:首先从所有样本中随机选定第一个聚类中心
# step2:记录所有样本到与其最近的聚类中心的距离
# step3:所有非聚类中心样本点被选取作为下一个聚类中心的概率与step2中的距离大小成正比,也就是说距离越远的样本点越有可能成为下一个聚类中心
# step4:重复step2和step3直至选出多个聚类中心

import numpy as np
import sklearn.datasets
from mnist import MNIST
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
import torch

def generate_data():
    # 本函数生成0-9,10个数字的图片矩阵
    image_data = []
    num_0 = torch.tensor(
        [[0, 0, 1, 1, 0, 0],
         [0, 1, 0, 0, 1, 0],
         [0, 1, 0, 0, 1, 0],
         [0, 1, 0, 0, 1, 0],
         [0, 0, 1, 1, 0, 0],
         [0, 0, 0, 0, 0, 0]])
    image_data.append(num_0)
    num_1 = torch.tensor(
        [[0, 0, 0, 1, 0, 0],
         [0, 0, 1, 1, 0, 0],
         [0, 0, 0, 1, 0, 0],
         [0, 0, 0, 1, 0, 0],
         [0, 0, 1, 1, 1, 0],
         [0, 0, 0, 0, 0, 0]])
    image_data.append(num_1)
    num_2 = torch.tensor(
        [[0, 0, 1, 1, 0, 0],
         [0, 1, 0, 0, 1, 0],
         [0, 0, 0, 1, 0, 0],
         [0, 0, 1, 0, 0, 0],
         [0, 1, 1, 1, 1, 0],
         [0, 0, 0, 0, 0, 0]])
    image_data.append(num_2)
    num_3 = torch.tensor(
        [[0, 0, 1, 1, 0, 0],
         [0, 0, 0, 0, 1, 0],
         [0, 0, 1, 1, 0, 0],
         [0, 0, 0, 0, 1, 0],
         [0, 0, 1, 1, 0, 0],
         [0, 0, 0, 0, 0, 0]])
    image_data.append(num_3)
    num_4 = torch.tensor(
        [
            [0, 0, 0, 0, 1, 0],
            [0, 0, 0, 1, 1, 0],
            [0, 0, 1, 0, 1, 0],
            [0, 1, 1, 1, 1, 1],
            [0, 0, 0, 0, 1, 0],
            [0, 0, 0, 0, 0, 0]])
    image_data.append(num_4)
    num_5 = torch.tensor(
        [
            [0, 1, 1, 1, 0, 0],
            [0, 1, 0, 0, 0, 0],
            [0, 1, 1, 1, 0, 0],
            [0, 0, 0, 0, 1, 0],
            [0, 1, 1, 1, 0, 0],
            [0, 0, 0, 0, 0, 0]])
    image_data.append(num_5)
    num_6 = torch.tensor(
        [[0, 0, 1, 1, 0, 0],
         [0, 1, 0, 0, 0, 0],
         [0, 1, 1, 1, 0, 0],
         [0, 1, 0, 0, 1, 0],
         [0, 0, 1, 1, 0, 0],
         [0, 0, 0, 0, 0, 0]])
    image_data.append(num_6)
    num_7 = torch.tensor(
        [
            [0, 1, 1, 1, 1, 0],
            [0, 0, 0, 0, 1, 0],
            [0, 0, 0, 1, 0, 0],
            [0, 0, 0, 1, 0, 0],
            [0, 0, 0, 1, 0, 0],
            [0, 0, 0, 0, 0, 0]])
    image_data.append(num_7)
    num_8 = torch.tensor(
        [[0, 0, 1, 1, 0, 0],
         [0, 1, 0, 0, 1, 0],
         [0, 0, 1, 1, 0, 0],
         [0, 1, 0, 0, 1, 0],
         [0, 0, 1, 1, 0, 0],
         [0, 0, 0, 0, 0, 0]])
    image_data.append(num_8)
    num_9 = torch.tensor(
        [[0, 0, 1, 1, 1, 0],
         [0, 1, 0, 0, 1, 0],
         [0, 0, 1, 1, 1, 0],
         [0, 1, 0, 0, 1, 0],
         [0, 0, 0, 0, 1, 0],
         [0, 0, 0, 0, 0, 0]])
    image_data.append(num_9)
    image_label = [0., 1., 2., 3., 4., 5., 6., 7., 8., 9.]
    return image_data, image_label

class KMcluster():
    def __init__(self, X, y, n_clusters=3, initialize="random", max_iters=10):
        self.X = X
        self.y = y
        self.n_clusters = n_clusters
        self.initialize = initialize
        self.max_iters = max_iters

    # 随机初始化中心点
    def init_random(self):
        # min, max = np.min(self.X)-1, np.max(self.X)+1
        # n_features = self.X.shape[1]
        # centroids = min + (max-min) * np.random.random((self.n_clusters, n_features))
        n_samples, n_features = self.X.shape
        centroids = self.X[np.random.choice(n_samples, self.n_clusters)]
        return centroids

    # KMeans++ 初始化中心点
    def init_kmeans_plusplus(self):
        n_samples, n_features = self.X.shape

        # step 1: 随机选取第一个中心点
        centroids = self.X[np.random.choice(n_samples, 1)]

        # 计算其余的中心点
        for k in range(0, self.n_clusters-1):
            distances = np.zeros((n_samples, k+1))

            # step 2: 计算每个样本到每一个聚类中心的欧式距离
            for i in range(len(centroids)):
                distances[:, i] = np.sqrt(np.sum(np.square(self.X - centroids[i]), axis=1))

            # step 3: 计算每个样本与最近聚类中心(指已选择的聚类中心)的距离D(x)
            # np.argmin
            dist = np.min(distances, axis=1)

            # step 4: 再取一个随机值,用权重的方式来取计算下一个“种子点”。具体实现是,先取一个能落在Sum(D(x))中的随机值Random,
            # 然后用Random -= D(x),直到其<=0,此时的点就是下一个“种子点”。
            total = np.sum(dist) * np.random.rand()
            for j in range(n_samples):
                total -= dist[j]
                if total > 0:
                    continue
                centroids = np.r_[centroids, self.X[j].reshape(-1, 2)]
                break

        # print(centroids)
        return centroids

    def assignment(self, centroids):
        n_samples = self.X.shape[0]
        distances = np.zeros((n_samples, self.n_clusters))
        for i in range(self.n_clusters):
            distances[:, i] = np.sum(np.square(self.X - centroids[i]), axis=1)
        return np.argmin(distances, axis=1)

    def update_center(self, flag, centroids):
        new_centroids = np.zeros_like(centroids)
        for i in range(self.n_clusters):
            new_centroids[i] = np.mean(self.X[flag == i], axis=0)
        return new_centroids

    def train(self):
        # step 1: generate center
        if self.initialize == "kmeans++":
            centroids = self.init_kmeans_plusplus()
        else:
            centroids = self.init_random()

        colmap = [i for i in range(self.n_clusters)]
        for i in range(self.max_iters):
            # step 2: assign centroid for each source data
            flag = self.assignment(centroids)

            #plt.scatter(self.X[:, 0], self.X[:, 1], c=flag, marker=".", alpha=0.5)
            #plt.scatter(centroids[:, 0], centroids[:, 1], c=colmap, marker="o", linewidths=6)
            #plt.show()

            # step 3: re-caculate center
            new_centroids = self.update_center(flag, centroids)

            # 终止条件,如果重新计算的中心点与上一次的重复,则退出训练
            if (new_centroids == centroids).all():
                break
            else:
                centroids = new_centroids

            print("iters: ", i, ", center point: ", centroids)


if __name__ == "__main__":

    '''
    # 生成数据集: X[2000, 2], y[2000], 4 clusters
    X, y = sklearn.datasets.make_blobs(n_samples=2000,
                                       n_features=2,
                                       centers=4,
                                      random_state=40,
                                       cluster_std=(2.5, 2, 2.5, 2))

    km = KMcluster(X, y, n_clusters=4, initialize="random", max_iters=50)
    # km = KMcluster(X, y, n_clusters=4, initialize="kmeans++", max_iters=50)
    km.train()

    '''

    # hct66 dataset
    image_data, image_label = generate_data() # generate source data
    image_label = np.array(image_label)
    col, row = image_data[0].shape
    image_values = np.zeros((len(image_label), col * row))
    import pdb
    pdb.set_trace()
    for idx, image_value in enumerate(image_data):
        image_values[idx, :] = image_value.flatten()

    # Normalize the data
    image_values_norm = StandardScaler().fit_transform(image_values)
    import pdb
    pdb.set_trace()
    # PCA 降维
    pca = PCA(n_components=6)
    image_values_pca = pca.fit(image_values_norm).transform(image_values_norm)
    print(image_values_pca.shape)
    #km = KMcluster(image_values_pca, image_label, n_clusters=3, initialize="random", max_iters=10)
    km = KMcluster(image_values_pca, image_label, n_clusters=3, initialize="keams++", max_iters=10)
    km.train()

二、图像滤波

1

  • 正弦曲线:
    y = A   s i n ( w x + b ) y = A\ sin(wx + b) y=A sin(wx+b)
import cv2
import numpy as np
import os
img  = cv2.imread("../week1/lena.jpg")
# # 图像滤波/卷积
kernel = np.ones((3,3),np.float32)/8
kernel=-kernel
kernel[0,:]=[-1,0,1]
kernel[1,:]=[-1,0,1]
kernel[2,:]=[-1,0,1]

print(kernel)
#plt.imshow(img)

#dst=cv.filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]]);当ddepth=-1>    时,表示输出图像与原图像有相同的深度。
print(img.shape)
result = cv2.filter2D(img,-1,kernel)
result.shape
print(result[0,0])
#plt.imshow(result*255)

result = cv2.filter2D(result,-1,kernel)
cv2.imwrite("filter2d_result.png",result)
os.system("open filter2d_result.png")
os.system("open ../week1/lena.jpg")

三、CNN

import torch
from torch import nn
import os

# 生成tensor
x = torch.tensor([[1.,2.,3.,7.],[6,3,4,2]])
# 也可以从图片中读取
print(x)

convolution=nn.Conv2d(1,1,kernel_size = 2,stride=2,padding=0)
#print(convolution(x))


# 查看卷积类都有哪些成员函数与成员变量
dir(convolution)
# 对x 进行维度变换
x1=x.view(1,1,2,4)
#with torch.no_grad()
print(convolution(x1))


#改变卷积核的取值
convolution.weight.data=torch.tensor([[[[1.,-1.],[1.,-1.]]]])
#改变偏移量得取值
convolution.bias.data =torch.tensor([0.0])
print(convolution(x1))

# 读取mnist数据
import sys
sys.path.append("../week4")
from mnist import MNIST
mndata = MNIST('../week4/mnist/python-mnist/data/')
image_data_all, image_label_all = mndata.load_training()
image_data=image_data_all[0:100]
image_label=image_label_all[0:100]

x = torch.tensor(image_data[0])
#np.array(image_data[3]).reshape((28,28)).astype('uint8')
img=x.view(1,1,28,28)

img_show=x.view(28,28)
import cv2
cv2.imwrite("img_show.png",img_show.numpy().astype("uint8"))
os.system("open img_show.png")

img = img.float()
feature= convolution(img)
feature_show =feature.view(15,15)
cv2.imwrite("feature_show.png",feature_show.detach().numpy().astype("uint8"))
os.system("open feature_show.png")
print(image_label)

def show_image(img):
    cv2.imwrite("tmp.png",img.detach().numpy().astype("uint8"))
    os.system("open tmp.png")

show_image(feature_show)
show_image(img_show)

show_image((convolution(torch.tensor(image_data[0]).view(1,1,28,28).float())).view(15,15))
conv2=nn.Conv2d(1,1,kernel_size = 2,stride=2,padding=1)
show_image((conv2(torch.tensor(image_data[0]).view(1,1,28,28).float())).view(15,15))

print("end")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值