按旋转角度二分类数据处理与训练

数据处理

import numpy as np
import operator
import os
import copy
from matplotlib.font_manager import FontProperties
from scipy.interpolate import lagrange
import random
import matplotlib.pyplot as plt
import math 
np.set_printoptions(suppress=True)
# 把opt文件内的逗号变为空格
#数据在我的百度云数据库txt文件,及opt文件
np.set_printoptions(threshold=np.inf) #输出全部矩阵不带省略号
random.seed(100)
##########################################
data = np.loadtxt('../txt/Vit_3Day.txt')
print(len(data))
# data = data[0:100]#抽取一部分
x1 = data[:,5]#x起点坐标
x2 = data[:,9]#x终点坐标
y1 = data[:,6]#y起
y2 = data[:,10]#y起
z1 = data[:,4]#IDpart
z2 = data[:,8]#IDpart
diam = data[:,12]
s1 = [a1 for a1 in range(1,len(x1)-1) if z1[a1]==z2[a1-1]!=-1 or z1[a1]!= z2[a1-1]]#id相同不等于0,或id不同
# print(s1)
lx = []#x1,x2相同的部分组成的列表
lxqi = []
lxzg = []
for i1 in range(len(s1)-1):
    b1 = x1[s1[i1]:s1[i1+1]]
    b1 = b1.tolist()
    b2 = x2[s1[i1+1]-1]#s1[i1]相当于a1
#     b1 = b1 + [b2]#把与x2最后相连的一个数和x1拼接起来
    b5 = z1[s1[i1]]#x,y起点id
    b1qi_id = [b5]+b1 +[b2]
    b6 = z2[s1[i1+1]-1]#x,y终点id
    b1zg_id = [b6] + b1+[b2]
    lx.append(b1)
    lxqi.append(b1qi_id)
    lxzg.append(b1zg_id)
###################################################
ly = []#y坐标以及管径大小
for i3 in range(len(s1)-1):
    b3 = y1[s1[i3]:s1[i3+1]]
    b3 = b3.tolist()
    b4 = y2[s1[i3+1]-1]#y最后一个不相等的数
    b3 = b3 + [b4]
    dm = diam[s1[i3+1]-1]
    b3 = b3 + [dm]#加上管径
    ly.append(b3)
#####################################################
#带有起点id的x坐标与y坐标合并
for q1 in range(len(lxqi)):
    for q2 in range(len(ly[q1])):
        lxqi[q1].append(ly[q1][q2])
#带有终点id的x坐标与y坐标合并
for p1 in range(len(lxzg)):
    for p2 in range(len(ly[p1])):
        lxzg[p1].append(ly[p1][p2])
lxqi.sort(key=operator.itemgetter(0))#排序,只按照第一个索引大小排序
tou = lxqi
lxzg.sort(key=operator.itemgetter(0))  
wei = lxzg 
# #########################################
toudeng = []
weideng = []
for dwei in wei:
    for i in range(len(tou)-1):
        if dwei[0] ==tou[i][0] and dwei[0]==tou[i+1][0]:
            toud = [dwei,tou[i],tou[i+1]]
            toudeng.append(toud)
for dtou in tou:
    for i in range(len(wei)-1):
        if dtou[0] == wei[i][0] and dtou[0]==wei[i+1][0]:
            weid = [wei[i],wei[i+1],dtou]
            weideng.append(weid)
# ###################################################
datatoudeng = []
dataweideng = []
#去掉起点id
for i in range(len(toudeng)):
    a = toudeng[i][0][1::]
    b = toudeng[i][1][1::]
    c = toudeng[i][2][1::]
    d = [a]+[b]+[c]
    datatoudeng.append(d)
for i in range(len(weideng)):
    a1 = weideng[i][0][1::]
    b1 = weideng[i][1][1::]
    c1 = weideng[i][2][1::]
    d1 = [a1]+[b1]+[c1]
    dataweideng.append(d1)
####################################################################
#判断管径信息是否加进列表,若未加进则只为x,y坐标,为偶数
for i in range(len(dataweideng)):
    a = dataweideng[i]
    assert len(a[0])%2==1
    assert len(a[1])%2==1
    assert len(a[2])%2==1
for i in range(len(datatoudeng)):
    a = datatoudeng[i]
    assert len(a[0])%2==1
    assert len(a[1])%2==1
    assert len(a[2])%2==1
final_tou = datatoudeng
##############################################################################
#将尾等分叉排列方式改为,与头等分叉相同的排列方式
final_wei = []
for i in range(len(dataweideng)):
    zhu = dataweideng[i][0]
    zuo = dataweideng[i][1]
    you = dataweideng[i][2]
    zhu_diam = [zhu[-1]]
    zuo_diam = [zuo[-1]]
    you_diam = [you[-1]]
    zhu_diam1 = [zhu[-1]]
    zuo_diam1 = [zuo[-1]]
    you_diam1 = [you[-1]]
    zhu_x = zhu[0:len(zhu)//2]
    zuo_x = zuo[0:len(zuo)//2]
    you_x = you[0:len(you)//2]
    zhu_y = zhu[len(zhu)//2:(len(zhu)-1)]
    zuo_y = zuo[len(zuo)//2:(len(zuo)-1)]
    you_y = you[len(you)//2:(len(you)-1)]
    #反转它们的顺序
    zhu_x1 = zhu_x[::-1]
    zuo_x1 = zuo_x[::-1]
    you_x1 = you_x[::-1]
    zhu_y1 = zhu_y[::-1]
    zuo_y1 = zuo_y[::-1]
    you_y1 = you_y[::-1]
    zhu_x = you_x1
    zuo_x = zhu_x1
    you_x = zuo_x1
    zhu_y = you_y1
    zuo_y = zhu_y1
    you_y = zuo_y1
    zhu_diam = you_diam1
    zuo_diam = zhu_diam1
    you_diam = zuo_diam1
    zhu_xy = zhu_x + zhu_y
    zuo_xy = zuo_x + zuo_y
    you_xy = you_x + you_y
    #这里再将坐标点与管径接起来
    zhu = zhu_xy + zhu_diam
    zuo = zuo_xy + zuo_diam
    you = you_xy + you_diam
    fencha = [zhu] + [zuo] + [you]
    final_wei.append(fencha)
# 这里是将分叉和汇聚都加在了一起
# final = final_tou + final_wei
# 若想把分叉和汇聚分开,则单独提取即可
final = final_tou
############################################################################
# 将所有的分叉主分支反转
final_zhu_reversed = []
for i in range(len(final)):
    zhu = final[i][0]
    zuo = final[i][1]
    you = final[i][2]
    zhu_diam = [zhu[-1]]
    zuo_diam = [zuo[-1]]
    you_diam = [you[-1]]
    zhu_x = zhu[0:len(zhu)//2]
    zuo_x = zuo[0:len(zuo)//2]
    you_x = you[0:len(you)//2]
    zhu_y = zhu[len(zhu)//2:(len(zhu)-1)]
    zuo_y = zuo[len(zuo)//2:(len(zuo)-1)]
    you_y = you[len(you)//2:(len(you)-1)]
    #反转它们的顺序
    zhu_x1 = zhu_x[::-1]
    zhu_y1 = zhu_y[::-1]
    zhu_x = zhu_x1
    zhu_y = zhu_y1
    zhu_xy = zhu_x + zhu_y
    zuo_xy = zuo_x + zuo_y
    you_xy = you_x + you_y
    #这里再将坐标点与管径接起来
    zhu = zhu_xy + zhu_diam
    zuo = zuo_xy + zuo_diam
    you = you_xy + you_diam
    fencha = [zhu] + [zuo] + [you]
    final_zhu_reversed.append(fencha)
final = final_zhu_reversed
############################################################################
# 可视化数据
# data = final
# for i in range(len(data)):
#         zhu = data[i][0]
#         zuo = data[i][1]
#         you = data[i][2]
#         print(zhu)
#         print(zuo)
#         print(you)
#         zhu_diam = [zhu[-1]]
#         zuo_diam = [zuo[-1]]
#         you_diam = [you[-1]]
#         zhu_x = zhu[0:len(zhu)//2]
#         zuo_x = zuo[0:len(zuo)//2]
#         you_x = you[0:len(you)//2]
#         zhu_y = zhu[len(zhu)//2:(len(zhu)-1)]
#         zuo_y = zuo[len(zuo)//2:(len(zuo)-1)]
#         you_y = you[len(you)//2:(len(you)-1)]
# #         print(zhu_x)
# #         print(zuo_x)
# #         print(you_x)
#         print("下一个")
##############################################################################
#去除重复的点(包括头部相等和尾部相等)
final1 = []
for i in range(len(final)):
    zhu = final[i][0]
    zuo = final[i][1]
    you = final[i][2]
    zhu_diam = [zhu[-1]]
    zuo_diam = [zuo[-1]]
    you_diam = [you[-1]]
    zhu_x = zhu[0:len(zhu)//2]
    zuo_x = zuo[0:len(zuo)//2]
    you_x = you[0:len(you)//2]
    zhu_y = zhu[len(zhu)//2:(len(zhu)-1)]
    zuo_y = zuo[len(zuo)//2:(len(zuo)-1)]
    you_y = you[len(you)//2:(len(you)-1)]
    ###########################################
    #前后不相等加进数组,最后再接上原始数组的最后一个
    zhu_x1 = []
    zhu_y1 = []
    for j in range(len(zhu_x)-1):
        if zhu_x[j] != zhu_x[j+1] or zhu_y[j] != zhu_y[j+1]:
            zhu_x1.append(zhu_x[j])
            zhu_y1.append(zhu_y[j])
    zhu_x1.append(zhu_x[-1])
    zhu_y1.append(zhu_y[-1])
     
    zuo_x1 = []
    zuo_y1 = []
    for j in range(len(zuo_x)-1):
        if zuo_x[j] != zuo_x[j+1] or zuo_y[j] != zuo_y[j+1]:
            zuo_x1.append(zuo_x[j])
            zuo_y1.append(zuo_y[j])
    zuo_x1.append(zuo_x[-1])
    zuo_y1.append(zuo_y[-1])
     
    you_x1 = []
    you_y1 = []
    for j in range(len(you_x)-1):
        if you_x[j] != you_x[j+1] or you_y[j] != you_y[j+1]:
            you_x1.append(you_x[j])
            you_y1.append(you_y[j])
    you_x1.append(you_x[-1])
    you_y1.append(you_y[-1])
    ###########################################
    zhu_xy = zhu_x1 + zhu_y1
    zuo_xy = zuo_x1 + zuo_y1
    you_xy = you_x1 + you_y1
    #这里再将坐标点与管径接起来
    zhu = zhu_xy + zhu_diam
    zuo = zuo_xy + zuo_diam
    you = you_xy + you_diam
    fencha = [zhu] + [zuo] + [you]
    final1.append(fencha)
final = final1
############################################################################
#可视化数据,观察哪些数据
# for i in range(len(final)):
#     print("第%d个分叉" %i)
#     for j in range(len(final[i])):
#         print(final[i][j])
#         print("**********************")
##############################################################################
#观察每一个分支有多少个坐标点,算上管径最多59,最少为7
axis_num_list = []
extract = []
for i in range(len(final)):
    for j in range(len(final[i])):
        axis_num = len(final[i][j])
        axis_num_list.append(axis_num)
for file in axis_num_list:
    if file < 33 :
        extract.append(file)
print(len(axis_num_list))
print(len(extract))
print(max(axis_num_list))
##################################################################################
# # 挑选出每个分支小于20个数的分叉
# select_final = []
# for i in range(len(final)):
#   point_num = 11
#   if len(final[])
#   print("下一个")
######################################################################################
# 挑选出每个分支小于33个数的分叉,x,y坐标个数分别为16,管径为1,这些点一个2830个,小于等于33的有2738个
select_final = []
for i in range(len(final)):
    point_num = 33
    if len(final[i][0]) <= point_num and len(final[i][1]) <= point_num and len(final[i][2]) <= point_num:
        select_final.append(final[i])
print("所有分叉:" ,len(final))
print("点数小于33分叉 : " , len(select_final))
final = select_final
#################################################################################
#计算两点之间距离
def get_len(x1,x2,y1,y2):
    diff_x = (x1-x2)**2
    diff_y = (y1-y2)**2
    length = np.sqrt(diff_x+diff_y)
    return length
###########################################################################
#旋转数据
def rotate(angle,valuex,valuey):
    valuex = np.array(valuex)
    valuey = np.array(valuey)
    rotatex = math.cos(angle)*valuex - math.sin(angle)*valuey
    rotatey = math.cos(angle)*valuey + math.sin(angle)*valuex
    rotatex = rotatex.tolist()
    rotatey = rotatey.tolist()
    return rotatex, rotatey
final2 = []
for i in range(len(final)):
    zhu = final[i][0]
    zuo = final[i][1]
    you = final[i][2]
    zhu_diam = [zhu[-1]]
    zuo_diam = [zuo[-1]]
    you_diam = [you[-1]]
    zhu_x = zhu[0:len(zhu)//2]
    zuo_x = zuo[0:len(zuo)//2]
    you_x = you[0:len(you)//2]
    zhu_y = zhu[len(zhu)//2:(len(zhu)-1)]
    zuo_y = zuo[len(zuo)//2:(len(zuo)-1)]
    you_y = you[len(you)//2:(len(you)-1)]
    ###########################################################
    #插值 最长为59,x,y为29
    insert_num = 16
    print(i)
    while len(zhu_x)< insert_num:
        zhu_lin_list = []
        for j in range(1,len(zhu_x)):
            zhu_lin_len = get_len(zhu_x[j-1],zhu_x[j],zhu_y[j-1],zhu_y[j])
            zhu_lin_list.append(zhu_lin_len)
        zhu_max_index = zhu_lin_list.index(max(zhu_lin_list)) #j-1
        #不处理的话会出现nan
        if abs(zhu_x[zhu_max_index]-zhu_x[zhu_max_index+1])==0:
            zhu_x[zhu_max_index+1] = zhu_x[zhu_max_index+1] +1
        zhu_insert_x = np.linspace(zhu_x[zhu_max_index],zhu_x[zhu_max_index+1],3)
        #插入的点
        zhu_insert_x = zhu_insert_x[1]
        f_zhu = lagrange([zhu_x[zhu_max_index],zhu_x[zhu_max_index+1]],[zhu_y[zhu_max_index],zhu_y[zhu_max_index+1]])
        zhu_insert_y = f_zhu(zhu_insert_x)
        zhu_x.insert(zhu_max_index+1,zhu_insert_x)
        zhu_y.insert(zhu_max_index+1,zhu_insert_y)
    while len(zuo_x) < insert_num:
        zuo_lin_list = []
        for j in range(1,len(zuo_x)):
            zuo_lin_len = get_len(zuo_x[j-1],zuo_x[j],zuo_y[j-1],zuo_y[j])
            zuo_lin_list.append(zuo_lin_len)
        zuo_max_index = zuo_lin_list.index(max(zuo_lin_list)) #对应j-1
        if abs(zuo_x[zuo_max_index]-zuo_x[zuo_max_index+1])==0:
            zuo_x[zuo_max_index+1] = zuo_x[zuo_max_index+1] + 1
        zuo_insert_x = np.linspace(zuo_x[zuo_max_index],zuo_x[zuo_max_index+1],3)
    #         #插入的点
        zuo_insert_x = zuo_insert_x[1]
        f_zuo = lagrange([zuo_x[zuo_max_index],zuo_x[zuo_max_index+1]],[zuo_y[zuo_max_index],zuo_y[zuo_max_index+1]])
        zuo_insert_y = f_zuo(zuo_insert_x)
        zuo_x.insert(zuo_max_index+1,zuo_insert_x)
        zuo_y.insert(zuo_max_index+1,zuo_insert_y)
    while len(you_x) < insert_num:
        you_lin_list = []
        for j in range(1,len(you_x)):
            #计算相邻两坐标的距离
            you_lin_len = get_len(you_x[j-1],you_x[j],you_y[j-1],you_y[j])
            #添加进列表中
            you_lin_list.append(you_lin_len)
        #计算距离最大的值对应的索引,对应x坐标的j-1和j之间的距离,最大
        you_max_index = you_lin_list.index(max(you_lin_list)) #对应j-1
        #然后,在两个最大点之间,平均插入一个数,作为插入x点
        if abs(you_x[you_max_index]-you_x[you_max_index+1]) == 0:
            you_x[you_max_index+1] = you_x[you_max_index+1] + 1
        you_insert_x = np.linspace(you_x[you_max_index],you_x[you_max_index+1],3)
        #插入的点
        you_insert_x = you_insert_x[1]
        #拉格朗日计算直线方程
        f_you = lagrange([you_x[you_max_index],you_x[you_max_index+1]],[you_y[you_max_index],you_y[you_max_index+1]])
        #插入的y点
        you_insert_y = f_you(you_insert_x)
        #将求得的x,y点插入对应位置
        you_x.insert(you_max_index+1,you_insert_x)
        you_y.insert(you_max_index+1,you_insert_y)
    ##############################################################################
    rotatedata = []
    # 在这里分类,不一定非要360度
    for j in range(180,360,1):
        zhu_rotatex, zhu_rotatey = rotate(j,zhu_x,zhu_y)
        zuo_rotatex, zuo_rotatey = rotate(j,zuo_x,zuo_y)
        you_rotatex, you_rotatey = rotate(j,you_x,you_y)
        rotatex = zhu_rotatex + zuo_rotatex + you_rotatex
        rotatey = zhu_rotatey + zuo_rotatey + you_rotatey
        #将列表变为数组方便后面进行加减运算
        zhu_rotatex = np.array(zhu_rotatex)
        zuo_rotatex = np.array(zuo_rotatex)
        you_rotatex = np.array(you_rotatex)
        zhu_rotatey = np.array(zhu_rotatey)
        zuo_rotatey = np.array(zuo_rotatey)
        you_rotatey = np.array(you_rotatey)
        #将旋转后的分叉,移到第一象限,x,y最小值都为0
        zhu_rotatex = zhu_rotatex - min(rotatex)
        zuo_rotatex = zuo_rotatex - min(rotatex)
        you_rotatex = you_rotatex - min(rotatex)
          
        zhu_rotatey = zhu_rotatey - min(rotatey)
        zuo_rotatey = zuo_rotatey - min(rotatey)
        you_rotatey = you_rotatey - min(rotatey)
        #再将数组变为列表方便拼接
        zhu_rotatex = zhu_rotatex.tolist()
        zuo_rotatex = zuo_rotatex.tolist()
        you_rotatex = you_rotatex.tolist()
        zhu_rotatey = zhu_rotatey.tolist()
        zuo_rotatey = zuo_rotatey.tolist()
        you_rotatey = you_rotatey.tolist()
        #######################################
        #可视化旋转效果
#         plt.scatter(zhu_rotatex,zhu_rotatey)
#         plt.scatter(zuo_rotatex,zuo_rotatey)
#         plt.scatter(you_rotatex,you_rotatey)
#         plt.xlim(0,1000)
#         plt.ylim(0,1000)
#         plt.show()
        ##########################################
        zhu_rotatexy = zhu_rotatex + zhu_rotatey
        zuo_rotatexy = zuo_rotatex + zuo_rotatey
        you_rotatexy = you_rotatex + you_rotatey
        #这里再将坐标点与管径接起来
        zhu_rotate = zhu_rotatexy + zhu_diam
        zuo_rotate = zuo_rotatexy + zuo_diam
        you_rotate = you_rotatexy + you_diam
        fencha = [zhu_rotate] + [zuo_rotate] + [you_rotate]
        rotatedata.append(fencha)
    final2.append(rotatedata)
final = []
for file in final2:
    for data in file:
        final.append(data)
####################################################################
all_point = []
all_diam = []
#找出来final中的最大值和最小值,方便后面进行归一化
for i in range(len(final)):
    zhu = final[i][0]
    zuo = final[i][1]
    you = final[i][2]
    zhu_diam = [zhu[-1]]
    zuo_diam = [zuo[-1]]
    you_diam = [you[-1]]
    zhu_x = zhu[0:len(zhu)//2]
    zuo_x = zuo[0:len(zuo)//2]
    you_x = you[0:len(you)//2]
    zhu_y = zhu[len(zhu)//2:(len(zhu)-1)]
    zuo_y = zuo[len(zuo)//2:(len(zuo)-1)]
    you_y = you[len(you)//2:(len(you)-1)]
    all_xy = zhu_x + zhu_y + zuo_x + zuo_y + you_x + you_y
    diam = zhu_diam + zuo_diam + you_diam
    for file in all_xy:
        all_point.append(file)
    for file in diam:
        all_diam.append(file)
max_point = max(all_point)
min_point = min(all_point)
#########################################################################
# 将数据分成几个部分
final1 = []
final2 = []
for i in range(len(final)):
    zhu = final[i][0]
    zuo = final[i][1]
    you = final[i][2]
    zhu_diam = [zhu[-1]]
    zuo_diam = [zuo[-1]]
    you_diam = [you[-1]]
    zhu_x = zhu[0:len(zhu)//2]
    zuo_x = zuo[0:len(zuo)//2]
    you_x = you[0:len(you)//2]
    zhu_y = zhu[len(zhu)//2:(len(zhu)-1)]
    zuo_y = zuo[len(zuo)//2:(len(zuo)-1)]
    you_y = you[len(you)//2:(len(you)-1)]
    all_xy = zhu_x + zhu_y + zuo_x + zuo_y + you_x + you_y
    if max(all_xy) < 270:
        final1.append(final[i])
    elif 270 <= max(all_xy) <=  max_point:
        final2.append(final[i])
print("final分叉:", len(final))
print("final1分叉: ",len(final1))
print("final2分叉: ",len(final2))
#########################################################################
#对所有的管径取log
all_diam = np.array(all_diam)
all_diam = np.log(all_diam)
max_diam = max(all_diam)
min_diam = min(all_diam)
print('max_point:',max_point)
print('min_point:',min_point)
print('max_diam:',max_diam)
print('min_diam:',min_diam)
###################################################################
#对坐标点和管径进行归一处理
select_final1 = True
# 加5或10的目的,是为了不让他们归一化后有等于1的值,只是靠近1,方便后面提取坐标
if select_final1:
    final = final1
    max_point = 270 
else:
    final = final2
    max_point = max_point 
print('max_point/3: ',max_point)
print('min_point/3: ',min_point)
final_norm = []
for i in range(len(final)):
    zhu = final[i][0]
    zuo = final[i][1]
    you = final[i][2]
    zhu_diam = [zhu[-1]]
    zuo_diam = [zuo[-1]]
    you_diam = [you[-1]]
    zhu_xy = final[i][0][0:-1]
    zuo_xy = final[i][1][0:-1]
    you_xy = final[i][2][0:-1]
    #列表变为数组
    zhu_xy = np.array(zhu_xy)
    zuo_xy = np.array(zuo_xy)
    you_xy = np.array(you_xy)
    #对坐标点进行归一化
    norm_zhu_xy = zhu_xy / max_point
    norm_zuo_xy = zuo_xy / max_point
    norm_you_xy = you_xy / max_point
    #将坐标点变为列表
    norm_zhu_xy = norm_zhu_xy.tolist()
    norm_zuo_xy = norm_zuo_xy.tolist()
    norm_you_xy = norm_you_xy.tolist()
    #对管径进行归一化
    norm_zhu_diam = [(math.log(zhu[-1]) - min_diam)/(max_diam -  min_diam)]
    norm_zuo_diam = [(math.log(zuo[-1]) - min_diam)/(max_diam -  min_diam)]
    norm_you_diam = [(math.log(you[-1]) - min_diam)/(max_diam -  min_diam)]
    norm_zhu = norm_zhu_xy + norm_zhu_diam
    norm_zuo = norm_zuo_xy + norm_zuo_diam
    norm_you = norm_you_xy + norm_you_diam
    norm = [norm_zhu] + [norm_zuo] + [norm_you]
    final_norm.append(norm)
final = final_norm
###########################################################################
#将在0-1角落的分叉移到0-1的中间
finaldata = []
for i in range(len(final)):
    zhu = final[i][0]
    zuo = final[i][1]
    you = final[i][2]
    zhu_diam = [zhu[-1]]
    zuo_diam = [zuo[-1]]
    you_diam = [you[-1]]
    zhu_x = zhu[0:len(zhu)//2]
    zuo_x = zuo[0:len(zuo)//2]
    you_x = you[0:len(you)//2]
    zhu_y = zhu[len(zhu)//2:(len(zhu)-1)]
    zuo_y = zuo[len(zuo)//2:(len(zuo)-1)]
    you_y = you[len(you)//2:(len(you)-1)]
    ######################################################################
    #平移之前可视化分叉图
#     print(zhu_x,zhu_y)
#     print(zuo_x,zuo_y)
#     print(you_x,you_y)
#     plt.plot(zhu_x,zhu_y)
#     plt.plot(zuo_x,zuo_y)
#     plt.plot(you_x,you_y)
#     plt.xlim(0.,1.)
#     plt.ylim(0.,1.)
#     plt.show()
    ######################################################################
    x = zhu_x + zuo_x + you_x
    y = zhu_y + zuo_y + you_y
    # x,y要移的大小
    translation_x = (1. - max(x)) / 2
    translation_y = (1. - max(y)) / 2
    zhu_x = np.array(zhu_x) + translation_x
    zuo_x = np.array(zuo_x) + translation_x
    you_x = np.array(you_x) + translation_x
    zhu_y = np.array(zhu_y) + translation_y
    zuo_y = np.array(zuo_y) + translation_y
    you_y = np.array(you_y) + translation_y
    #再将x,y坐标变为列表
    zhu_x = zhu_x.tolist()
    zuo_x = zuo_x.tolist()
    you_x = you_x.tolist()
    zhu_y = zhu_y.tolist()
    zuo_y = zuo_y.tolist()
    you_y = you_y.tolist()
    ###################################################################
    #平移之后可视化分叉图
#     print(zhu_x,zhu_y)
#     print(zuo_x,zuo_y)
#     print(you_x,you_y)
#     plt.plot(zhu_x,zhu_y)
#     plt.plot(zuo_x,zuo_y)
#     plt.plot(you_x,you_y)
#     plt.xlim(0.,1.)
#     plt.ylim(0.,1.)
#     plt.show()
  #####################################################################
    #在此改变要补充的值,与排列的顺序
    #每个分支个数不一样,在每个分支x,y坐标后补1,然后单独的一个管径后面也补1,最后合在一块的管径不1,都到30
    insert_zhu_diam = zhu_diam + [1.] * (insert_num - len(zhu_diam))
    insert_zuo_diam = zuo_diam + [1.] * (insert_num - len(zuo_diam))
    insert_you_diam = you_diam + [1.] * (insert_num - len(you_diam))
    diam = zhu_diam + zuo_diam + you_diam
    insert_diam = diam + [1.] * (insert_num - len(diam)) 
    insert = [zhu_x] + [zuo_x] + [you_x] + [zhu_y] + [zuo_y] + [you_y] + [insert_zhu_diam] + [insert_zuo_diam] +[insert_you_diam] + [insert_diam] 
    finaldata.append(insert)
finaldata = np.array((finaldata)) 
ones = np.ones((len(finaldata),6,16))
finaldata = np.concatenate((finaldata,ones),1)
finaldata = finaldata.reshape(-1,16,16,1)
# np.random.shuffle(finaldata)
print(finaldata.shape)
finaldata_label = []
for i in range(len(finaldata)):
  # 此处需根据旋转度数更改
  one_hot = [0,1]
  label = np.array(one_hot)
  finaldata_label.append((finaldata[i],label))
finaldata = np.array(finaldata_label)
print(finaldata.shape)
print(finaldata[0])
##################################################################################
# 保存与加载数据与标签
np.save('data/360.npy',finaldata)
# print("完成")
# finaldata = np.load('data/data.npy')
# finallabel = np.load('data/label.npy')
##################################################################################
# 分离标签和数据
def input_data(finaldata):
  data = []
  label = []
  for i in range(len(finaldata)):
    data.append(finaldata[i][0])
    label.append(finaldata[i][1])
  data = np.array(data)
  label = np.array(label)
  return data, label
# finaldata,datalabel = input_data(finaldata)
# print(finaldata.shape)
# print(datalabel.shape)
##################################################################################
def save_images(finaldata):
# 挑选出坐标点,并可视化
# (-1,10,10)
    finaldata = finaldata.reshape(-1,16,16)
    for i in range(len(finaldata)):
        zhu_x = finaldata[i][0]
        zuo_x = finaldata[i][1]
        you_x = finaldata[i][2]
        zhu_y = finaldata[i][3]
        zuo_y = finaldata[i][4]
        you_y = finaldata[i][5]
        zhu_diam = finaldata[i][6][0]        
        zuo_diam = finaldata[i][7][0]
        you_diam = finaldata[i][8][0]
        ori_zhu_diam = (max_diam - min_diam) * zhu_diam + min_diam
        ori_zuo_diam = (max_diam - min_diam) * zuo_diam + min_diam 
        ori_you_diam = (max_diam - min_diam) * you_diam + min_diam
        plt.scatter(zhu_x,zhu_y, color='red', linewidth=ori_zhu_diam)
        plt.scatter(zuo_x,zuo_y, color='green', linewidth=ori_zuo_diam)
        plt.scatter(you_x,you_y, color='blue', linewidth=ori_you_diam)
        plt.xlim(0.,1.)
        plt.ylim(0.,1.)
#         plt.savefig("C:\\Users\\Administrator\\Desktop\\a\\%d.jpg" %i)
#         plt.close()
        plt.show()
#####################################################################################
# save_images(finaldata)

分为训练集和测试集

import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
data0 = np.load("data/180.npy")
data1 = np.load("data/360.npy")
# 先打乱一下数据
np.random.shuffle(data0)
np.random.shuffle(data1)
print(data0.shape)
print(data1.shape)
# 剩下得做为验证集
data0_val = data0[110000::,:]
data1_val = data1[110000::,:]

# 每类挑出十万个作为训练集
data0 = data0[0:110000,:]
data1 = data1[0:110000,:]
data = np.concatenate((data0,data1),0)
data_val = np.concatenate((data0_val,data1_val),0)
np.random.shuffle(data)
np.random.shuffle(data_val)
print(data[0])
print(data.shape)
print(data_val.shape)
###########################################################################
# np.save('data/2训练集.npy',data)
# np.save('data/2测试集.npy',data_val)
############################################################################
# 分离数据与标签
def input_data(finaldata):
  data = []
  label = []
  for i in range(len(finaldata)):
    data.append(finaldata[i][0])
    label.append(finaldata[i][1])
  data = np.array(data)
  label = np.array(label)
  return data, label
# finaldata,datalabel = input_data(data)
# print(finaldata.shape)
# print(datalabel.shape)
# 
# print(datalabel[100020])
# print(datalabel[200030])
##################################################################################
def save_images(finaldata):
# 挑选出坐标点,并可视化
# (-1,10,10)
    finaldata = finaldata.reshape(-1,16,16)
    for i in range(len(finaldata)):
        zhu_x = finaldata[i][0]
        zuo_x = finaldata[i][1]
        you_x = finaldata[i][2]
        zhu_y = finaldata[i][3]
        zuo_y = finaldata[i][4]
        you_y = finaldata[i][5]
        zhu_diam = finaldata[i][6][0]        
        zuo_diam = finaldata[i][7][0]
        you_diam = finaldata[i][8][0]
        plt.scatter(zhu_x,zhu_y, color='red')
        plt.scatter(zuo_x,zuo_y, color='green')
        plt.scatter(you_x,you_y, color='blue')
        plt.xlim(0.,1.)
        plt.ylim(0.,1.)
#         plt.savefig("C:\\Users\\Administrator\\Desktop\\a\\%d.jpg" %i)
#         plt.close()
        plt.show()
#####################################################################################
# save_images(finaldata)

训练模型

import tensorflow as tf
import numpy as np 
import os 
np.set_printoptions(threshold=np.inf)
#######################################################################
# 读取数据和标签
finaldata = np.load("../data/2训练集.npy") # 316, 999
finalval = np.load("../data/2测试集.npy")  # 316, 999
print(finaldata.shape)
np.random.seed(1000)
np.random.shuffle(finaldata)
np.random.shuffle(finalval)
########################################################################
# 超参数
batch_size = 100
learning_rate = 0.001
epochs = 10000
n_class = 2
#######################################################################
# 用numpy进行one_hot编码
def np_one_hot(labels):
  n_labels = np.max(labels) + 1
  one_hot = np.eye(n_labels)[labels]
  
  return one_hot
######################################################################
# 将数据与标签分离,并对标签进行one_hot编码
def input_data(finaldata):
  data = []
  label = []
  for i in range(len(finaldata)):
    data.append(finaldata[i][0])
    label.append(finaldata[i][1])
  data = np.array(data)
  data = data.reshape(-1,16,16,1)
  label = np.array(label)
  # 这时的数据处理方式已经是one_hot形式不需要,再进行one_hot编码
#   label = np_one_hot(label)
  
  return data, label
# 训练集
data, label = input_data(finaldata)
# 测试集
data_val, label_val = input_data(finalval)
###########################################################################
# 排除管径对分类的影响
ones = np.ones((len(data),10,16,1))
data[:,6::,:,:]  = ones
val_ones = np.ones((len(data_val),10,16,1))
data_val[:,6::,:,:] = val_ones
###########################################################################
# 得到batch个数据
# 有数据有label时
def get_batch(inputs=None, labels=None, batch_size=None, shuffle=True):
  assert len(inputs) == len(labels)
  indices = np.arange(len(inputs))
  if shuffle:
    np.random.shuffle(indices)
  # start_idx为batch_size个数
  for start_idx in range(0, len(inputs) -batch_size + 1, batch_size):
    if shuffle:
      excerpt = indices[start_idx:start_idx + batch_size]
    else:
      excerpt = indices[start_idx:start_idx + batch_size]
    yield inputs[excerpt] , labels[excerpt]
#####################################################################
def inference(images):
  
  # conv1 16x16x1->16x16x96
  with tf.variable_scope("conv1") as scope:
    weights = tf.get_variable("weights",
                              shape = [3, 3, 1, 96],
                              dtype = tf.float32,
                              initializer = tf.truncated_normal_initializer(stddev=0.05,dtype=tf.float32))
    biases = tf.get_variable("biases",
                             shape = [96],
                             dtype = tf.float32,
                             initializer = tf.constant_initializer(0.0))
    conv = tf.nn.conv2d(images, weights, strides=[1, 1, 1, 1], padding="SAME")
    pre_activation = tf.nn.bias_add(conv, biases)
    conv1 = tf.nn.relu(pre_activation, name=scope.name)
    
  
  # pool1 and norm1 16x16x96->8x8x96
  with tf.variable_scope("pooling1_lrn") as scope:
    pool1 = tf.nn.max_pool(conv1, ksize=[1, 3, 3, 1], strides=[1, 2, 2 ,1],
                           padding="SAME", name="pooing1")
    norm1 = tf.nn.lrn(pool1, depth_radius=4, bias=1.0, alpha=0.001/9.0,
                      beta=0.75, name="norm1")
  
  # conv2 8x8x96->8x8x64
  with tf.variable_scope("conv2") as scope:
    weights = tf.get_variable("weights",
                              shape = [3, 3, 96, 64],
                              dtype = tf.float32,
                              initializer = tf.truncated_normal_initializer(stddev=0.05,dtype=tf.float32))
    biases = tf.get_variable('biases',
                                 shape=[64], 
                                 dtype=tf.float32,
                                 initializer=tf.constant_initializer(0.1))
    conv = tf.nn.conv2d(norm1, weights, strides=[1,1,1,1],padding='SAME')
    pre_activation = tf.nn.bias_add(conv, biases)
    conv2 = tf.nn.relu(pre_activation, name='conv2')
    
    
  #pool2 and norm2 8x8x64->4x4x64
  with tf.variable_scope('pooling2_lrn') as scope:
      norm2 = tf.nn.lrn(conv2, depth_radius=4, bias=1.0, alpha=0.001/9.0,
                        beta=0.75,name='norm2')
      pool2 = tf.nn.max_pool(norm2, ksize=[1,3,3,1], strides=[1,1,1,1],
                             padding='SAME',name='pooling2')
  print(pool2.shape)
  # fc3
  with tf.variable_scope("fc3") as scope:
    reshape = tf.reshape(pool2, shape=[-1, 8*8*64])
    print(reshape.shape)
    dim = reshape.get_shape()[1].value
    weights = tf.get_variable("weights",
                              shape=[dim, 512],
                              dtype=tf.float32,
                              initializer=tf.truncated_normal_initializer(stddev=0.004,dtype=tf.float32))
    biases = tf.get_variable("biases",
                             shape=[512],
                             dtype = tf.float32,
                             initializer = tf.constant_initializer(0.1) )
    fc3 = tf.nn.relu(tf.matmul(reshape,weights) + biases, name=scope.name)
    
  
  # fc4
  with tf.variable_scope('fc4') as scope:
      weights = tf.get_variable('weights',
                                shape=[512,256],
                                dtype=tf.float32, 
                                initializer=tf.truncated_normal_initializer(stddev=0.004,dtype=tf.float32))
      biases = tf.get_variable('biases',
                               shape=[256],
                               dtype=tf.float32,
                               initializer=tf.constant_initializer(0.1))
      local4 = tf.nn.relu(tf.matmul(fc3, weights) + biases, name='fc4')

  # softmax
  with tf.variable_scope('softmax_linear') as scope:
      weights = tf.get_variable('softmax_linear',
                                shape=[256, n_class],
                                dtype=tf.float32,
                                initializer=tf.truncated_normal_initializer(stddev=0.004,dtype=tf.float32))
      biases = tf.get_variable('biases', 
                               shape=[n_class],
                               dtype=tf.float32, 
                               initializer=tf.constant_initializer(0.1))
      softmax_linear = tf.add(tf.matmul(local4, weights), biases, name='softmax_linear')
  
  return softmax_linear

######################################################################
# loss函数
def losses(logits, labels):
    with tf.variable_scope('loss') as scope:
        # to use this loss fuction, one-hot encoding is needed!
        cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=labels, name='xentropy_per_example')
        loss = tf.reduce_mean(cross_entropy, name='loss')
        if not os.path.exists('loss'):
          os.makedirs('loss')
        tf.summary.scalar(scope.name+'/loss', loss)
        
    return loss
###################################################################################
images = tf.placeholder(tf.float32,[None, 16, 16, 1])
labels = tf.placeholder(tf.float32,[None, n_class])
####################################################################################
# 训练模型
def train():
  my_global_step = tf.Variable(0, name='global_step', trainable=False)
  logits = inference(images)
  
  prediction = tf.nn.softmax(logits)
  correct_prediction = tf.equal(tf.argmax(prediction,1),tf.argmax(labels,1))
  
  # loss值
  loss = losses(logits, labels)
  
  # 准确率
  accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
  
  
  train_op = tf.train.AdamOptimizer(learning_rate).minimize(loss, global_step = my_global_step)
  
  
  saver = tf.train.Saver(tf.global_variables())
  
  summary_op = tf.summary.merge_all()
  
  sess = tf.Session()
  sess.run(tf.global_variables_initializer())
  
  if not os.path.exists('logs'):
    os.makedirs('logs')
  summary_writer = tf.summary.FileWriter('logs',sess.graph)
  
  for e in range(epochs):
    for data_batch,label_batch in get_batch(data,label,batch_size):
      
      _, loss_value ,train_accuracy_value= sess.run([train_op, loss, accuracy], feed_dict={images:data_batch,labels:label_batch}) 
      # 测试机准确率
      test_accuraccy_value = sess.run(accuracy,feed_dict={images:data_val,labels:label_val})
      print("第%d个epoch: , loss: %.4f, train_accuracy: %.4f, test_accuracy: %.4f" % (e, loss_value, train_accuracy_value,test_accuraccy_value))
    
    if e % 3 ==0:
      summary_str = sess.run(summary_op, feed_dict={images:data_batch, labels:label_batch})
      summary_writer.add_summary(summary_str, e)
      saver.save(sess,"checkpoints/model.ckpt", global_step=e)
  
  sess.close()

train()
def evaluate():
    logits = inference(images)
    # softmax变为概率,若预测正确,其中最大值接近1
    prediction = tf.nn.softmax(logits)
    # 预测的最大值的索引,也即使哪一类
    prediction_max = tf.argmax(prediction,1)
    # 真实的label
    label_max = tf.argmax(labels,1)
    # 为布尔值
    correct_prediction = tf.equal(tf.argmax(prediction,1),tf.argmax(labels,1))
    # 将布尔值变为小数
    accuracy_arr = tf.cast(correct_prediction, tf.float32)
    # 取这一批的ping'jun'zhi
#     accuracy_arr = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
    with tf.Session() as sess:
      saver = tf.train.Saver(tf.global_variables())
      saver.restore(sess, tf.train.latest_checkpoint("checkpoints"))
      for test_data, test_label in get_batch(data_val, label_val, 1):
        prediction_index,label_index,acc = sess.run([prediction_max,label_max,accuracy_arr],feed_dict={images:test_data,labels:test_label})
        prob = acc[0]
        print("prob: %.4f " % prob," pre_index:",prediction_index," label_index:",label_index)
        

# evaluate()




猜你喜欢

转载自blog.csdn.net/qq_38826019/article/details/83213141