先附上一个python小模块,可以有效的控制tensorflow信息提示,一般设为2就可以了
import os
def level(level):
level=str(level)
os.environ["TF_CPP_MIN_LOG_LEVEL"] = level
""" TF_CPP_MIN_LOG_LEVEL = 1 //默认设置,为显示所有信息
TF_CPP_MIN_LOG_LEVEL = 2 //只显示error和warining信息
TF_CPP_MIN_LOG_LEVEL = 3 //只显示error信息
"""
在做遥感影像分类的cnn时,tfcords实在是烦,各种各样的问题,例如tensor数据不能作为输入,例如一直卡住不动(我知道TensorFlow是用一个线程去读取数据,一个去运算,就是数据没有读取成功,所以一直卡着不动,也写了oord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess=sess, coord=coord),但是任然没有什么效果,有比较熟练tfcords的可以教我一下吗?难道是硬件问题?)
自己写的读取数据集,不用考虑他们有多少类别什么的,读取时会自动打上标签,我用的是256256的,把的变为了2828的
第一步
遥感影像一般是多个通道,我把他们转换为了jpg,并且去掉其中不是3个通道的
import os
from PIL import Image
import re
import numpy as np
def type_to_jpg(original_dir,now_dir,t):
"""
:param original_dir: #原始图片的存放目录,类别的上级目录
:param now_dir: #转换为jpg的存放目录,剔除不是3通道的,压缩图片
:param t: 压缩图片为几×几
:return:
"""
os.makedirs(now_dir,exist_ok=True) #创建新主目录,就是类别的上级目录
for i in os.listdir(original_dir):
os.makedirs(now_dir+'/'+i,exist_ok=True) #创建新的类别目录
for root,dirs,files in os.walk(original_dir): #转换成就jpg
for file in files:
if os.path.splitext(file)[1]=='.tif':
lu=root+'/'+file
img=Image.open(lu)
img=img.resize((t,t)) #重新resize
img.save(now_dir +'/'+ re.split('/', root)[-1]+'/'+ os.path.splitext(file)[0]+ '.jpg')#保存图片
return 0
def copy_dir_to_newdir(dir,newdir):#自己试的时候用到的函数
"""
:param dir: 原来的文件夹目录
:param newdir: 现在的文件夹目录
:return: 把原来文件夹下的所有目录加入到新的文件夹下,不会添加里面的内容,如果不存在新文件夹,会自动创建,不管有多少层目录
"""
a = []
for i in os.listdir(dir):
a.append(i)
os.makedirs(newdir,exist_ok=True)
for i in a:
os.makedirs(newdir+i,exist_ok=True)
def list_count(now_dir):
"""
:param dir: jpg图片存放目录
:return: 打印出每一类的数量
"""
a=[]
for root, dirs, files in os.walk(now_dir):
a.append(files)
for i in range(1,22):
print(len(a[i]),end=" ")
print()
def delete_not_3(now_dir):
"""
:param now_dir: jpg图片存放目录
:return: 删除不是3个通道的图片
"""
for root, dirs, files in os.walk(now_dir):
for file in files:
if os.path.splitext(file)[1] == '.jpg':
lu = root + '/' + file
img=Image.open(lu)
#采用捕获异常的形式筛选出哪些不是目标图片
try:
image = np.reshape(img, [28, 28, 3])
except:
print(lu)
os.remove(lu)
return 0
if __name__=='__main__':
#参数自己修改
original_dir = './UCMerced_LandUse/Images/'
now_dir = './own_image/images/'
t=28
type_to_jpg(original_dir,now_dir,t)
list_count(now_dir)
delete_not_3(now_dir)
list_count(now_dir)
原始图片样式
转换后的图片:
第二步
实现get_data,自己设计写读数据集的时候还是有点问题,就换了一种思路,把制作数据集的过程省略了,上面筛选图片就相当于制作数据集了。
import numpy as np
import os
import cv2 #我用的opencv_python-4.0.0-cp36-cp36m-win_amd64.whl
import re
def get_class(dir):
"""
:param dir: 图片存放路径
:return: 类别列表
"""
l=[] #保存所有类别名称
for i in os.listdir(dir):
l.append(i)
return l
def get_img_dirs(dir):
"""
:param dir: 图片存放路径
:return: 所有图片路径列表
"""
l=[] #保存所有图片路径
for root,dirs,files in os.walk(dir):
for file in files:
if os.path.splitext(file)[1]=='.jpg':
l.append(root+'/'+file)
return l
def get_own_img_data(imgs,cla,batch_size):
"""
为了实现更快速,随机,本来想存txt里的,感觉又有点麻烦,读取也不方便
索性就设置随机图片制作数据组和列表
如果想让它训练次数少一点,并且更合理的随机
可以给随机数加上列表-随机数字次数,控制一下
这里没有加
:param imgs: 所有图片目录列表
:param cla: 所有类别列表
:param batch_size: 一组的大小
:return: img,label
"""
batch=[] #保存随机选取batch_size个图片的路径
for i in range(batch_size):
rng=np.random.randint(0,len(imgs))
batch.append(imgs[rng])
l=[] #把batch里面的图片用cv2读取,并且转换为np数组,用于输入
for img in batch:
im=cv2.imread(img)
a=np.reshape(im,(28,28,3))
l.append(a*(1./255))
label=[] #保存每个batch里面图片的标签,采用[0,0,0,1,0],这样的格式
for img in batch:
a=[0 for i in range(len(cla))]
index=cla.index(re.split('/',img)[-2]) #判断对应图片所属类别
a[index]=1
label.append(a)
return l,label
def main(batch_size):
#cnn读取数据时的接口函数
dir = './own_image/images/'
cla=get_class(dir)
imgs=get_img_dirs(dir)
data=get_own_img_data(imgs,cla,batch_size)
return data
第三部
用cnn训练
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
STEPS=5000
for i in range(STEPS):
data = get.main(BATCH_SIZE)
if i%100==0:
train_accuracy = accuracy.eval(feed_dict={x: data[0], y_: data[1], keep_prob: 1.0})
print('step %d, training accuracy %g' % (i, train_accuracy))
sess.run(train_step, feed_dict={x: data[0], y_: data[1], keep_prob: 0.5})
saver.save(sess, './own_image/model/model.ckpt')
data1 = get.main(2000)
print('test accuracy %g' % accuracy.eval(feed_dict={
x: data1[0], y_:data1[1], keep_prob: 1.0}))
我是21类256*256的遥感影像,每类100张,没有做test图片,训练过程中accuracy在五千次以后基本就为1了,最终用2000张训练过的去测试,accuracy为1.当然这有些含糊
**
如果有更好更方便的方式,可以一起交流啊
**