原料
windows10+python3.5+pycharm
安裝tensorflow
利用Tensorflow訓(xùn)練搭建自己的物體訓(xùn)練模型,萬里長征第一步,先安裝tensorflow。
tensorflow分為cpu版和gpu版,gpu版的運(yùn)行速度是cpu的50倍,但是gpu版的坑太多,要安裝許多開發(fā)套件,對windows的支持不夠友好;更為致命的是,它需要Nvida的中高端顯卡,我的電腦系統(tǒng)是windows10,顯卡是入門級顯卡,開始我還想掙扎一下,安裝個gpu版,大概試了一個晚上,到底是沒有成功,識時務(wù)者為俊杰,那就安裝cpu版的吧。
pip insatll tensorflow
假如沒有報(bào)錯,做個測試,運(yùn)行以下代碼
import tensorflow as tf
#指定一個常數(shù)張量
first_blood = tf.constant('double kill')
#創(chuàng)建一個會話,方便查看結(jié)果
sess = tf.Session()
print(str(sess.run(first_blood)))
運(yùn)行結(jié)果如下
E:\python\python.exe "E:/pycharm src/TF/__init__.py"
2018-12-01 23:33:25.181550: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
double kill
Process finished with exit code 0
如果出現(xiàn)警告:
Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
翻譯過來的大致意思是:
你的CPU支持AVX擴(kuò)展,但是你安裝的TensorFlow版本無法編譯使用
此時需要在第一行代碼前加上兩行代碼:
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
# 指定一個常數(shù)張量
first_blood = tf.constant('double kill')
# 創(chuàng)建一個會話,方便查看結(jié)果
sess = tf.Session()
print(str(sess.run(first_blood)))
下載Tensorflow object detection API
如果有g(shù)it的話,右鍵git bash,使用命令下載:
git clone https://github.com/tensorflow/models.git
或者直接打開網(wǎng)站:
點(diǎn)擊綠色按鈕->downlaod zip
下載好之后,把文件解壓,注意解壓路徑不要包含中文,比如我的解壓后的路徑是:
C:\Users\lenovo\Desktop\note\gitclone\models
如果下載速度很慢,可以參考:https://blog.csdn.net/ygdxt/article/details/82825013
下載并配置protoc
在https://github.com/google/protobuf/releases中選擇windows版本:

只有win32,也就是windows32位的,64位是兼容32位的。
下載好之后,解壓,把bin目錄下的protoc.exe復(fù)制到..\models\research文件夾下。
接著就是配置protoc了,在打開cmd下切換到..\models\research目錄,
執(zhí)行命令protoc object_detection\protos\*.proto --python_out=.
如果報(bào)以下的錯(其實(shí)很大可能性會報(bào)錯,無論是不是在管理員模式下):
object_detection\protos*.proto: No such file or directory
則需要對指令做修改,指令protoc object_detection\protos\*.proto --python_out=.中的*.proto表示是對research目錄下的所有后綴名為proto的文件做操作,那干脆我們把指令中的*.proto這部分改成所有后綴名為proto的文件,每執(zhí)行一次,就會生成一個.py文件,由于文件太多,我已經(jīng)把指令寫成腳本:
import os
path_url = os.path.join(os.getcwd(),r"object_detection\protos")
print("proto path:",path_url)
for file in os.listdir(path_url):
cmd = "protoc object_detection\protos\{} --python_out=."
if file.endswith(".proto"):
command = cmd.format(file)
print("excuting command:",command)
os.popen(command)
在..\research目錄下新建一個文件excuter.py,把以上代碼復(fù)制進(jìn)去,保存運(yùn)行,稍等一會兒就可以看到..\research\object_detection\protos目錄下生成了許多.py文件,說明protoc配置成功。
models環(huán)境變量配置
配置環(huán)境變量
依次打開:我的電腦--->高級系統(tǒng)設(shè)置--->環(huán)境變量,新建一個系統(tǒng)變量:


系統(tǒng)變量名只要不和已有的重復(fù),符合命令規(guī)范,沒有其他要求,我這里是
tensorflow
系統(tǒng)變量名下有兩個值,..\research和..\research\slim的絕對路徑。
測試
在..\research下打開cmd,運(yùn)行以下命令,
python object_detection/builders/model_builder_test.py
如果出現(xiàn)錯誤:

報(bào)錯原因是你的models路徑太長,python無法找指定模塊,
解決辦法是在你的python安裝路徑下新建一個tensorflow_model.pth文件
(比如我的是E:\python\Lib\site-packages)
把寫到環(huán)境變量里的那兩個路徑復(fù)制到該文件中。

再運(yùn)行命令python object_detection/builders/model_builder_test.py

說明配置成功
利用tensorflow自帶模型測試
測試的圖片是在
C:\Users\lenovo\Desktop\note\gitclone\models\research\object_detection\test_images
我們看到這里有現(xiàn)成的兩張圖片,當(dāng)然也可以換成自己的。
測試的腳本是
C:\Users\lenovo\Desktop\note\gitclone\models\research\object_detection\object_detection_tutorial.ipynb
這是一個需要用jupyter notebook打開的文件,不過好像在jupyter notebook運(yùn)行會有許多毛病
我已經(jīng)把這個ipynb文件改寫成py文件,并修復(fù)了一些未知問題,文件內(nèi)容如下:
import numpy as np
import os
import six.moves.urllib as urllib
import sys
import tarfile
import tensorflow as tf
import zipfile
from distutils.version import StrictVersion
from collections import defaultdict
from io import StringIO
from matplotlib import pyplot as plt
from PIL import Image
# This is needed since the notebook is stored in the object_detection folder.
sys.path.append("..")
from object_detection.utils import ops as utils_ops
if StrictVersion(tf.__version__) < StrictVersion('1.9.0'):
raise ImportError('Please upgrade your TensorFlow installation to v1.9.* or later!')
import numpy as np
import os
import six.moves.urllib as urllib
import sys
import tarfile
import tensorflow as tf
import zipfile
from distutils.version import StrictVersion
from collections import defaultdict
from io import StringIO
from matplotlib import pyplot as plt
from PIL import Image
# This is needed since the notebook is stored in the object_detection folder.
sys.path.append("..")
from object_detection.utils import ops as utils_ops
if StrictVersion(tf.__version__) < StrictVersion('1.9.0'):
raise ImportError('Please upgrade your TensorFlow installation to v1.9.* or later!')
from utils import label_map_util
from utils import visualization_utils as vis_util
# What model to download.
MODEL_NAME = 'ssd_mobilenet_v1_coco_2017_11_17'
MODEL_FILE = MODEL_NAME + '.tar.gz'
DOWNLOAD_BASE = 'http://download.tensorflow.org/models/object_detection/'
# Path to frozen detection graph. This is the actual model that is used for the object detection.
PATH_TO_FROZEN_GRAPH = MODEL_NAME + '/frozen_inference_graph.pb'
# List of the strings that is used to add correct label for each box.
PATH_TO_LABELS = os.path.join('data', 'mscoco_label_map.pbtxt')
opener = urllib.request.URLopener()
opener.retrieve(DOWNLOAD_BASE + MODEL_FILE, MODEL_FILE)
tar_file = tarfile.open(MODEL_FILE)
for file in tar_file.getmembers():
file_name = os.path.basename(file.name)
if 'frozen_inference_graph.pb' in file_name:
tar_file.extract(file, os.getcwd())
detection_graph = tf.Graph()
with detection_graph.as_default():
od_graph_def = tf.GraphDef()
with tf.gfile.GFile(PATH_TO_FROZEN_GRAPH, 'rb') as fid:
serialized_graph = fid.read()
od_graph_def.ParseFromString(serialized_graph)
tf.import_graph_def(od_graph_def, name='')
category_index = label_map_util.create_category_index_from_labelmap(PATH_TO_LABELS, use_display_name=True)
def load_image_into_numpy_array(image):
(im_width, im_height) = image.size
return np.array(image.getdata()).reshape(
(im_height, im_width, 3)).astype(np.uint8)
# For the sake of simplicity we will use only 2 images:
# image1.jpg
# image2.jpg
# If you want to test the code with your images, just add path to the images to the TEST_IMAGE_PATHS.
PATH_TO_TEST_IMAGES_DIR = 'test_images'
TEST_IMAGE_PATHS = [ os.path.join(PATH_TO_TEST_IMAGES_DIR, 'image{}.jpg'.format(i)) for i in range(1, 3) ]
# Size, in inches, of the output images.
IMAGE_SIZE = (12, 8)
output_num = 1
output_img_dic = r'\output_images'
def run_inference_for_single_image(image, graph):
with graph.as_default():
with tf.Session() as sess:
# Get handles to input and output tensors
ops = tf.get_default_graph().get_operations()
all_tensor_names = {output.name for op in ops for output in op.outputs}
tensor_dict = {}
for key in [
'num_detections', 'detection_boxes', 'detection_scores',
'detection_classes', 'detection_masks'
]:
tensor_name = key + ':0'
if tensor_name in all_tensor_names:
tensor_dict[key] = tf.get_default_graph().get_tensor_by_name(
tensor_name)
if 'detection_masks' in tensor_dict:
# The following processing is only for single image
detection_boxes = tf.squeeze(tensor_dict['detection_boxes'], [0])
detection_masks = tf.squeeze(tensor_dict['detection_masks'], [0])
# Reframe is required to translate mask from box coordinates to image coordinates and fit the image size.
real_num_detection = tf.cast(tensor_dict['num_detections'][0], tf.int32)
detection_boxes = tf.slice(detection_boxes, [0, 0], [real_num_detection, -1])
detection_masks = tf.slice(detection_masks, [0, 0, 0], [real_num_detection, -1, -1])
detection_masks_reframed = utils_ops.reframe_box_masks_to_image_masks(
detection_masks, detection_boxes, image.shape[0], image.shape[1])
detection_masks_reframed = tf.cast(
tf.greater(detection_masks_reframed, 0.5), tf.uint8)
# Follow the convention by adding back the batch dimension
tensor_dict['detection_masks'] = tf.expand_dims(
detection_masks_reframed, 0)
image_tensor = tf.get_default_graph().get_tensor_by_name('image_tensor:0')
# Run inference
output_dict = sess.run(tensor_dict,
feed_dict={image_tensor: np.expand_dims(image, 0)})
# all outputs are float32 numpy arrays, so convert types as appropriate
output_dict['num_detections'] = int(output_dict['num_detections'][0])
output_dict['detection_classes'] = output_dict[
'detection_classes'][0].astype(np.uint8)
output_dict['detection_boxes'] = output_dict['detection_boxes'][0]
output_dict['detection_scores'] = output_dict['detection_scores'][0]
if 'detection_masks' in output_dict:
output_dict['detection_masks'] = output_dict['detection_masks'][0]
return output_dict
for image_path in TEST_IMAGE_PATHS:
image = Image.open(image_path)
# the array based representation of the image will be used later in order to prepare the
# result image with boxes and labels on it.
image_np = load_image_into_numpy_array(image)
# Expand dimensions since the model expects images to have shape: [1, None, None, 3]
image_np_expanded = np.expand_dims(image_np, axis=0)
# Actual detection.
output_dict = run_inference_for_single_image(image_np, detection_graph)
# Visualization of the results of a detection.
vis_util.visualize_boxes_and_labels_on_image_array(
image_np,
output_dict['detection_boxes'],
output_dict['detection_classes'],
output_dict['detection_scores'],
category_index,
instance_masks=output_dict.get('detection_masks'),
use_normalized_coordinates=True,
line_thickness=8)
plt.figure(figsize=IMAGE_SIZE)
print(1,image_np)
plt.imshow(image_np)
plt.show()
global output_num
global output_img_dic
if not os.path.exists(output_img_dic):
os.mkdir(output_img_dic)
output_img_path = os.path.join(output_img_dic,str(output_num)+".png")
plt.savefig(output_img_path)
運(yùn)行上述代碼需要安裝
matplotlib庫,直接pip install matplotlib安裝失敗的可以去官網(wǎng)安裝與python版本對應(yīng)的whl文件。安裝matplotlib.whl時需要先出pycharm。
同時由于需要下載模型文件,需要在網(wǎng)絡(luò)好的情況下進(jìn)行測試。否則就會報(bào)HTTP ERROR錯誤
運(yùn)行效果圖

