python連接redis-九游会j9娱乐平台
⑴ 如何在後台部署深度學習模型
搭建深度學習後台伺服器
我們的keras深度學習rest api將能夠批量處理圖像,擴展到多台機器(包括多台web伺服器和redis實例),並在負載均衡器之後進行循環調度。
為此,我們將使用:
kerasredis(內存數據結構存儲)
flask (python的微web框架)
消息隊列和消息代理編程範例
- redis-server
- python run_keras_server.py
- curl -x post -f [email protected] 'http://localhost:5000/predict'
- {"predictions": [{"label": "beagle","probability": 0.9461546540260315},{"label": "bluetick","probability": 0.031958919018507004},{"label": "redbone","probability": 0.006617196369916201},{"label": "walker_hound","probability": 0.0033879687543958426},{"label": "greater_swiss_mountain_dog","probability": 0.0025766862090677023}],"success": true}
- # import the necessary packagesimport requests# initialize the keras rest api endpoint url along with the input# image pathkeras_rest_api_url = "http://localhost:5000/predict"image_path = "jemma.png"
- # load the input image and construct the payload for the requestimage = open(image_path, "rb").read()payload = {"image": image}# submit the requestr = requests.post(keras_rest_api_url, files=payload).json()# ensure the request was sucessfulif r["success"]: # loop over the predictions and display them for (i, result) in enumerate(r["predictions"]): print("{}. {}: {:.4f}".format(i 1, result["label"], result["probability"]))# otherwise, the request failedelse: print("request failed")
- python simple_request.py
本篇文章的整體思路如下:
我們將首先簡要討論redis數據存儲,以及如何使用它促進消息隊列和消息代理。然後,我們將通過安裝所需的python包來配置python開發環境,以構建我們的keras深度學習rest api。一旦配置了開發環境,就可以使用flask web框架實現實際的keras深度學習rest api。在實現之後,我們將啟動redis和flask伺服器,然後使用curl和python向我們的深度學習api端點提交推理請求。最後,我們將以對構建自己的深度學習rest api時應該牢記的注意事項的簡短討論結束。
第一部分:簡要介紹redis如何作為rest api消息代理/消息隊列
測試和原文的命令一致。
第三部分:配置python開發環境以構建keras rest api
文章中說需要創建新的虛擬環境來防止影響系統級別的python項目(但是我沒有創建),但是還是需要安裝rest api所需要依賴的包。以下為所需要的包。
第四部分:實現可擴展的keras rest api
首先是keras redis flask rest api數據流程圖
讓我們開始構建我們的伺服器腳本。為了方便起見,我在一個文件中實現了伺服器,但是它可以按照您認為合適的方式模塊化。為了獲得最好的結果和避免復制/粘貼錯誤,我建議您使用本文的「下載」部分來獲取相關的腳本和圖像。
為了簡單起見,我們將在imagenet數據集上使用resnet預訓練。我將指出在哪裡可以用你自己的模型交換resnet。flask模塊包含flask庫(用於構建web api)。redis模塊將使我們能夠與redis數據存儲介面。從這里開始,讓我們初始化將在run_keras_server.py中使用的常量.
我們將向伺服器傳遞float32圖像,尺寸為224 x 224,包含3個通道。我們的伺服器可以處理一個batch_size = 32。如果您的生產系統上有gpu(s),那麼您需要調優batch_size以獲得最佳性能。我發現將server_sleep和client_sleep設置為0.25秒(伺服器和客戶端在再次輪詢redis之前分別暫停的時間)在大多數系統上都可以很好地工作。如果您正在構建一個生產系統,那麼一定要調整這些常量。
讓我們啟動我們的flask app和redis伺服器:
在這里你可以看到啟動flask是多麼容易。在運行這個伺服器腳本之前,我假設redis伺服器正在運行(之前的redis-server)。我們的python腳本連接到本地主機6379埠(redis的默認主機和埠值)上的redis存儲。不要忘記將全局keras模型初始化為none。接下來我們來處理圖像的序列化:
redis將充當伺服器上的臨時數據存儲。圖像將通過諸如curl、python腳本甚至是移動應用程序等各種方法進入伺服器,而且,圖像只能每隔一段時間(幾個小時或幾天)或者以很高的速率(每秒幾次)進入伺服器。我們需要把圖像放在某個地方,因為它們在被處理前排隊。我們的redis存儲將作為臨時存儲。
為了將圖像存儲在redis中,需要對它們進行序列化。由於圖像只是數字數組,我們可以使用base64編碼來序列化圖像。使用base64編碼還有一個額外的好處,即允許我們使用json存儲圖像的附加屬性。
base64_encode_image函數處理序列化。類似地,在通過模型傳遞圖像之前,我們需要反序列化圖像。這由base64_decode_image函數處理。
預處理圖片
我已經定義了一個prepare_image函數,它使用keras中的resnet50實現對輸入圖像進行預處理,以便進行分類。在使用您自己的模型時,我建議修改此函數,以執行所需的預處理、縮放或規范化。
從那裡我們將定義我們的分類方法
classify_process函數將在它自己的線程中啟動,我們將在下面的__main__中看到這一點。該函數將從redis伺服器輪詢圖像批次,對圖像進行分類,並將結果返回給客戶端。
在model = resnet50(weights="imagenet")這一行中,我將這個操作與終端列印消息連接起來——根據keras模型的大小,載入是即時的,或者需要幾秒鍾。
載入模型只在啟動這個線程時發生一次——如果每次我們想要處理一個映像時都必須載入模型,那麼速度會非常慢,而且由於內存耗盡可能導致伺服器崩潰。
載入模型後,這個線程將不斷輪詢新的圖像,然後將它們分類(注意這部分代碼應該時尚一部分的繼續)
在這里,我們首先使用redis資料庫的lrange函數從隊列(第79行)中獲取最多的batch_size圖像。
從那裡我們初始化imageids和批處理(第80和81行),並開始在第84行開始循環隊列。
在循環中,我們首先解碼對象並將其反序列化為一個numpy數組image(第86-88行)。
接下來,在第90-96行中,我們將向批處理添加圖像(或者如果批處理當前為none,我們將該批處理設置為當前圖像)。
我們還將圖像的id附加到imageids(第99行)。
讓我們完成循環和函數
在這個代碼塊中,我們檢查批處理中是否有圖像(第102行)。如果我們有一批圖像,我們通過模型(第105行)對整個批進行預測。從那裡,我們循環一個圖像和相應的預測結果(110-122行)。這些行向輸出列表追加標簽和概率,然後使用imageid將輸出存儲在redis資料庫中(第116-122行)。
我們使用第125行上的ltrim從隊列中刪除了剛剛分類的圖像集。最後,我們將睡眠設置為server_sleep時間並等待下一批圖像進行分類。下面我們來處理/predict我們的rest api端點
稍後您將看到,當我們發布到rest api時,我們將使用/predict端點。當然,我們的伺服器可能有多個端點。我們使用@app。路由修飾符以第130行所示的格式在函數上方定義端點,以便flask知道調用什麼函數。我們可以很容易地得到另一個使用alexnet而不是resnet的端點,我們可以用類似的方式定義具有關聯函數的端點。你懂的,但就我們今天的目的而言,我們只有一個端點叫做/predict。
我們在第131行定義的predict方法將處理對伺服器的post請求。這個函數的目標是構建json數據,並將其發送回客戶機。如果post數據包含圖像(第137和138行),我們將圖像轉換為pil/pillow格式,並對其進行預處理(第141-143行)。
在開發這個腳本時,我花了大量時間調試我的序列化和反序列化函數,結果發現我需要第147行將數組轉換為c-contiguous排序(您可以在這里了解更多)。老實說,這是一個相當大的麻煩事,但我希望它能幫助你站起來,快速跑。
如果您想知道在第99行中提到的id,那麼實際上是使用uuid(通用唯一標識符)在第151行生成的。我們使用uuid來防止hash/key沖突。
接下來,我們將圖像的id和base64編碼附加到d字典中。使用rpush(第153行)將這個json數據推送到redis db非常簡單。
讓我們輪詢伺服器以返回預測
我們將持續循環,直到模型伺服器返回輸出預測。我們開始一個無限循環,試圖得到157-159條預測線。從這里,如果輸出包含預測,我們將對結果進行反序列化,並將結果添加到將返回給客戶機的數據中。我們還從db中刪除了結果(因為我們已經從資料庫中提取了結果,不再需要將它們存儲在資料庫中),並跳出了循環(第163-172行)。
否則,我們沒有任何預測,我們需要睡覺,繼續投票(第176行)。如果我們到達第179行,我們已經成功地得到了我們的預測。在本例中,我們向客戶機數據添加true的成功值(第179行)。注意:對於這個示例腳本,我沒有在上面的循環中添加超時邏輯,這在理想情況下會為數據添加一個false的成功值。我將由您來處理和實現。最後我們稱燒瓶。jsonify對數據,並將其返回給客戶端(第182行)。這就完成了我們的預測函數。
為了演示我們的keras rest api,我們需要一個__main__函數來實際啟動伺服器
第186-196行定義了__main__函數,它將啟動classify_process線程(第190-192行)並運行flask應用程序(第196行)。
第五部分:啟動可伸縮的keras rest api
要測試我們的keras深度學習rest api,請確保使用本文的「下載」部分下載源代碼示例圖像。從這里,讓我們啟動redis伺服器,如果它還沒有運行:
然後,在另一個終端中,讓我們啟動rest api flask伺服器:
另外,我建議在向伺服器提交請求之前,等待您的模型完全載入到內存中。現在我們可以繼續使用curl和python測試伺服器。
第七部分:使用curl訪問keras rest api
使用curl來測試我們的keras rest api伺服器。這是我的家庭小獵犬jemma。根據我們的resnet模型,她被歸類為一隻擁有94.6%自信的小獵犬。
你會在你的終端收到json格式的預測:
第六部分:使用python向keras rest api提交請求
如您所見,使用curl驗證非常簡單。現在,讓我們構建一個python腳本,該腳本將發布圖像並以編程方式解析返回的json。
讓我們回顧一下simple_request.py
我們在這個腳本中使用python請求來處理向伺服器提交數據。我們的伺服器運行在本地主機上,可以通過埠5000訪問端點/predict,這是keras_rest_api_url變數(第6行)指定的。
我們還定義了image_path(第7行)。png與我們的腳本在同一個目錄中。如果您想測試其他圖像,請確保指定到您的輸入圖像的完整路徑。
讓我們載入圖像並發送到伺服器:
我們在第10行以二進制模式讀取圖像並將其放入有效負載字典。負載通過請求發送到伺服器。在第14行發布。如果我們得到一個成功消息,我們可以循環預測並將它們列印到終端。我使這個腳本很簡單,但是如果你想變得更有趣,你也可以使用opencv在圖像上繪制最高的預測文本。
第七部分:運行簡單的請求腳本
編寫腳本很容易。打開終端並執行以下命令(當然,前提是我們的flask伺服器和redis伺服器都在運行)。
使用python以編程方式使用我們的keras深度學習rest api的結果
第八部分:擴展深度學習rest api時的注意事項
如果您預期在深度學習rest api上有較長一段時間的高負載,那麼您可能需要考慮一種負載平衡演算法,例如循環調度,以幫助在多個gpu機器和redis伺服器之間平均分配請求。
記住,redis是內存中的數據存儲,所以我們只能在隊列中存儲可用內存中的盡可能多的圖像。
使用float32數據類型的單個224 x 224 x 3圖像將消耗602112位元組的內存。
⑵ python安裝hiredis一直報錯什麼。。求解。環境是win64下
很稿薯明顯你的環顫粗境里沒有sys/socket.h這茄敬鎮個頭文件。hiredis是依賴c庫hiredis的python擴展,要編譯的。
fatal error: sys/socket.h: no such file or directory
#include
⑶ python怎麼測試與redis的連接
redis服務端:192.168.100.132;port=6379
redis客戶端:192.168.100.132
客戶端操作:
安裝python支持redis;
tar zxvf redis-2.9.1.tar.gz
cd redis-2.9.1
python setup.py install
服務端啟動redis
/root/redis-2.2.12/src/redis-server
客戶端測試:
[root@master ~]# python
>>> import redis
>>> r = redis.redis(host='192.168.100.132',port=6379,db=0) //#如果設置了密碼,就加上password=密碼
>>> r.set('name','lansgg')
true
>>> r.get('name')
'lansgg'
>>> r.exists('name') //#看是否存在這個鍵值
true
>>> r.delete('name')
1
>>> r.dbsize() //#庫里有多少key,多少條數據
0l
>>> r.set('name','lansgg')
true
>>> r.flushdb() // #刪除當前資料庫的所有數據
true
>>> r.get('name')
>>> r.set('name','lansgg')
true
>>> r.set('wm','leo')
true
>>> r.set('tt','coffee')
true
>>> r.keys() // # 列出所有鍵值。
['tt', 'wm', 'name']
>>> r.save() // #強行把資料庫保存到硬碟。保存時阻塞
true
>>> r.dbsize()
3l
>>> dir(r)
['response_callbacks', '__class__', '__contains__', '__delattr__', '__delitem__', '__dict__', '__doc__', '__format__', '__getattribute__', '__getitem__', '__hash__', '__init__', '__mole__', '__new__', '__rece__', '__rece_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_zaggregate', 'append', 'bgrewriteaof', 'bgsave', 'bitcount', 'bitop', 'blpop', 'brpop', 'brpoplpush', 'client_getname', 'client_kill', 'client_list', 'client_setname', 'config_get', 'config_resetstat', 'config_set', 'connection_pool', 'dbsize', 'debug_object', 'decr', 'delete', 'mp', 'echo', 'eval', 'evalsha', 'execute_command', 'exists', 'expire', 'expireat', 'flushall', 'flushdb', 'from_url', 'get', 'getbit', 'getrange', 'getset', 'hdel', 'hexists', 'hget', 'hgetall', 'hincrby', 'hincrbyfloat', 'hkeys', 'hlen', 'hmget', 'hmset', 'hscan', 'hset', 'hsetnx', 'hvals', 'incr', 'incrby', 'incrbyfloat', 'info', 'keys', 'lastsave', 'lindex', 'linsert', 'llen', 'lock', 'lpop', 'lpush', 'lpushx', 'lrange', 'lrem', 'lset', 'ltrim', 'mget', 'move', 'mset', 'msetnx', 'object', 'parse_response', 'persist', 'pexpire', 'pexpireat', 'ping', 'pipeline', 'psetex', 'pttl', 'publish', 'pubsub', 'randomkey', 'register_script', 'rename', 'renamenx', 'response_callbacks', 'restore', 'rpop', 'rpoplpush', 'rpush', 'rpushx', 'sadd', 'save', 'scan', 'scard', 'script_exists', 'script_flush', 'script_kill', 'script_load', 'sdiff', 'sdiffstore', 'sentinel', 'sentinel_get_master_addr_by_name', 'sentinel_masters', 'sentinel_sentinels', 'sentinel_slaves', 'set', 'set_response_callback', 'setbit', 'setex', 'setnx', 'setrange', 'shutdown', 'sinter', 'sinterstore', 'sismember', 'slaveof', 'smembers', 'smove', 'sort', 'spop', 'srandmember', 'srem', 'sscan', 'strlen', 'substr', 'sunion', 'sunionstore', 'time', 'transaction', 'ttl', 'type', 'unwatch', 'watch', 'zadd', 'zcard', 'zcount', 'zincrby', 'zinterstore', 'zrange', 'zrangebyscore', 'zrank', 'zrem', 'zremrangebyrank', 'zremrangebyscore', 'zrevrange', 'zrevrangebyscore', 'zrevrank', 'zscan', 'zscore', 'zunionstore']
這只是一個簡單的測試,為了測試redis是否正常工作,我們安裝是否正確;
⑷ redis 一個資料庫能存多少數據
redis一個實例能存一個key或是value大小最大是512m。操作方法如下:
1、首先要安裝redis,開啟redis的服務。
⑸ 用python查詢redis數據,結果中前面為什麼總是有字母b
你好,你是用python3吧,在前面有個b』表示是bytes
解決方法:
#網路www.iwithb.com
importredis
importconfig.configasconf
redis=redis.redis(host=conf.redis_host,port=conf.redis_port,password=conf.redis_password)
redis.sadd('iwithb',"hello")
url=redis.spop("iwithb")
print(str(url,encoding='utf-8'))
#這樣就沒有b了,注意str(url,encoding='utf-8')
⑹ python把字典存到redis怎麼使用
python把字典存到redis怎麼使用
先寫個測試redis是否正常連接上
import redis
cache = redis.strictredis('172.20.0.227',6379)
存儲字元串
key = "javaman_test"
value = "test_string_yy"
cachevalue = cache.get(key)
存儲dict對象,取出來為字元串
value = {"id":1,"name":"sunxy"}
cache.set(key,value,60)
cachevalue = cache.get(key)
print type(value),type(cachevalue)
這時使用eval()對獲取的結果轉換成dict
cachevalue = cache.get(key)
trans_value = eval(cachevalue)
print type(trans_value),trans_value.get("name")
如果不是一個dict,直接是一個對象呢?
之前用了django中的對象,來看一下
取出來仍然是字元串,如何把對象存進去呢
eval()只是將結果轉換成字典,這個肯定不行,我們應該需要將對象存到redis中。
使用pickle模塊,在存入到redis中時調用mps函數,獲取後調用loads函數
import pickleredis.set(key,pickle.mps(xt_instry),180)
pickle.loads(result)
⑺ python-redis鏈接redis怎麼認證
利用r=reids.redis(host='localhost', port=6379,db=0)也可以。
區別:redis是strictredis的子類,用於向後兼容舊版本的redis-py。
⑻ redis伺服器無法啟動或無法連接上
錯誤信息:job for redis-server.service failed because the control process exited with error code. see "systemctl status redis-server.service" and "journalctl -xe" for details.
或者客戶端去鏈接時的錯誤信息:
could not connect to redis at 127.0.0.1:6379: connection refused
could not connect to redis at 127.0.0.1:6379: connection refused
ps -ef|grep redis 查看redis伺服器進程
sudo kill -9 pid 殺死redis伺服器
sudo redis-server /etc/redis/redis.conf 指定載入的配置文件
把redis的所有顯示的都殺掉,包括
python 104924 103363 0 00:08 pts/23 00:00:00 grep --color=auto redis
但是這個是會自動重啟的,這就對了。
然後再次 sudo redis-server /etc/redis/redis.conf 啟動
連接redis
redis-cli
就完成了。