#注意在.py文件相同目錄下放一個1.png作測試圖片 #本質就是用html來實現圖片 #寫在前面的話:這個程序在python自帶ide裏面遇到bug就秒退,看不了提示信息 #解決方法以下: #用cmd 在文件目錄裏面執行python lastversion.py便可運行 #而且能夠進行調試,會返回出錯信息,比自帶ide好多了. #總之:別用ide來調試. #English for upper Chinese: #use cmd 's command python lastversion.py to run this programe. #cause it's more convinient to debug from PyQt5 import QtWidgets from PyQt5.QtWidgets import QFileDialog from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtWidgets import QFileDialog from PyQt5 import QtWidgets from PyQt5.QtWidgets import QFileDialog import codecs import sys import os def i(a,*arg): f=open(a,'w') f.write(arg[0]) #我以前出錯全是由於write裏面不能寫數字 #只能寫字符串,這點跟print不同.#這裏面不要忘了寫[0] f.close() pass class MyWindow(QtWidgets.QWidget): def __init__(self): super(MyWindow,self).__init__() self.resize(800,800) self.myButton = QtWidgets.QPushButton(self) self.myButton.setObjectName("myButton") self.myButton.setText("Open") self.myButton.clicked.connect(self.load) self.myButton2 = QtWidgets.QPushButton(self) self.myButton2.setObjectName("myButton") self.myButton2.setText("save") self.myButton2.clicked.connect(self.save) self.myButton2.move(200,0) self.myButton3 = QtWidgets.QPushButton(self) self.myButton3.setObjectName("myButton") self.myButton3.setText("run") self.myButton3.clicked.connect(self.run) self.myButton3.move(400,0) self.textEdit = QtWidgets.QTextEdit(self) self.textEdit.setGeometry(QtCore.QRect(10, 40, 801, 521)) self.textEdit.setObjectName("textEdit") self.textEdit.resize(1500,600) #write something self.textEdit.insertPlainText('print (42389)\r\n')#\r\n是換行 self.textEdit.insertPlainText('print (423893)\r\n') self.textEdit.insertPlainText('print (423893)\r\n') self.textEdit.insertPlainText('print (423893)\r\n') #下面就是用html語言來插入圖片 self.textEdit.insertHtml('<img src=1.png>' ) #用html來保存就好了,利用下面4行測試了一下效果不錯. def load(self): fileName1, filetype = QFileDialog.getOpenFileName(self, "選取文件", "D:/", "Text Files (*.txt)") #設置文件擴展名過濾,注意用雙分號間隔 #read就是全讀取這些都好使 text=open(fileName1,'r').read() self.textEdit.setText(text) def save(self): fileName2, ok2 = QFileDialog.getSaveFileName(self, "文件保存", "D:/", "All Files (*);;Text Files (*.txt)") my_text=self.textEdit.toHtml() my_text=str(my_text) i(fileName2,my_text)#i就是讀入函數的本體. def run(self): a=self.textEdit.toPlainText() #obj表明圖片. b='' for i in a: if i !='': b+=i a=b f = open("file1.py", "w") # 打開文件 #下面這行write寫不了??爲何是否是qt模塊衝突 f.write(a) f.close() #關閉文件 b=os.getcwd() #獲得D:\桌面使用大全\repos #如今只能這樣用這個方式調用cmd來運行python os.system('python '+b+'\\file1.py') if __name__=="__main__": f = open("file3.py", "w") # 打開文件 #下面這行write寫不了??爲何是否是qt模塊衝突 f.write('32131231111111111111111111') f.close() print (4324) app=QtWidgets.QApplication(sys.argv) myshow=MyWindow() myshow.show() sys.exit(app.exec_())
功能:把圖片1.png放在這個文件的同目錄下,就會在文件裏面看到這個圖片,利用html來實現的.php
裏面輸入的python代碼點run就會運行.帶保存和打開文件功能.圖片插入信息也能保存下來html
●爬取百度貼吧任意一個吧的圖片html5
from urllib.request import urlopen from bs4 import BeautifulSoup from urllib.request import urlopen import re import random import os import urllib.request #把base_url隨便改爲別的貼吧的吧的首頁或者任意一頁都行 base_url = "https://tieba.baidu.com/f?kw=%E4%B8%96%E7%95%8C%E6%9D%AF" num=0 for i in range(0,50):#爬取50頁 #這地方寫的不對,因該用正則提取後面的pn #下面在加一個判斷,是否你貼入的base_url是首頁.由於首頁後面沒有&pn處理不一樣: a=re.findall(".*&pn",base_url) shumu=50*i print ('正在爬取第'+str(i+1)+'頁的全部帖子裏面的圖片') if a==[]: #那麼咱們就加入&pn=... url=base_url+'&pn='+str(shumu) else: url=base_url+str(shumu) #把url地址裏面的東西讀出來給soup try:#用try來解決有時候編碼utf-8很差使的問題 html = urlopen(url).read().decode('utf-8') except Exception: continue soup = BeautifulSoup(html, features='lxml') #把地址裏面的每個頁碼地址都取出來 #這個正則表達式表示開頭必須是/p的,裏面有/p後不少數字的,(?=)這個叫斷言,利用這個來加限制條件 #繼續搞一個貪婪匹配和非貪婪匹配的區別 .*?5表示非貪婪匹配 235235會出來2個235 .*5是貪婪匹配235235會出來235235 sub_urls = soup.find_all("a", {"target": "_blank", "href": re.compile("(?=^/p)/p/\d*")}) for i in range(len(sub_urls)): a=sub_urls[i]['href']#利用這個方式提取一個網址裏面的href #這裏面每個a就是要爬取的網頁 #下面開始爬取他的圖片 baseurl='https://tieba.baidu.com' url=baseurl+str(a) try: html = urlopen(url).read().decode('utf-8') except Exception: continue soup = BeautifulSoup(html, features='lxml') #soup裏面進入標籤的方法是.標籤就好了所謂標籤就是<a>...<\a>這裏面東西就是a標籤裏面的內容 tupian=soup.cc #繼續加一個功能若是須要保存到的dir不存在就生成,存在就pass aaa=os.path.exists('d:/tupian') if aaa!=True: os.makedirs('d:/tupian') #先設置一下保存的位置: dir=r'D:\tupian' #這個目錄先本身手動創立一下 #而後直接find img get src可是有的cc裏面沒有圖片 try: if tupian!=None and tupian.find_all('img')!=None: img_srcall = tupian.find_all('img') #注意find的話後面能夠直接.get find_all後面不能直接.get for _ in img_srcall: #這個pic_name還必需要寫一個拓展名 img_src=_.get('src') #繼續再加個判斷只下載有size的圖片,這樣就跳過了圖標文件 a=_.get('size') #這個get方法真心好用,他的效果是若有有size這個屬性咱們 #就返回他,不然咱們返回None,永遠不會報錯的. if a!=None and int(a)>30000: pic_name=str(num) pic_name=pic_name+img_src[-4:] pic_name=os.path.join(dir,pic_name) urllib.request.urlretrieve(img_src, pic_name) num+=1 except Exception: continue
功能:把一個吧裏面從任意一頁開始開始爬全部他和他後面的頁裏面的size大於30000的圖片.保存到D:\tupianjava
細節:利用urlopen模塊解析url再decode成urf-8.由於有中文.配合正則表達式和beautifulsoup來匹配圖片url.利用urllib.request.urlretrieve來下載圖片node
●用python創建最簡單的服務器python
import sys, os, subprocess from http.server import BaseHTTPRequestHandler,HTTPServer class ServerException(Exception): '''服務器內部錯誤''' pass #下面是全部事件的處理 class base_case(object):#這個類是全部處理的共性.因此設立一個base_case來描述,下面的處理來 #繼承基類就好了 '''條件處理基類''' def handle_file(self, handler, full_path): try: with open(full_path, 'rb') as reader: content = reader.read() #read讀取所有內容 handler.send_content(content) except IOError as msg: msg = "'{0}' cannot be read: {1}".format(full_path, msg) handler.handle_error(msg) def index_path(self, handler): return os.path.join(handler.full_path, 'index.html') def test(self, handler): assert False, 'Not implemented.' def act(self, handler): assert False, 'Not implemented.' class case_no_file(base_case): '''文件或目錄不存在''' def test(self, handler): return not os.path.exists(handler.full_path) def act(self, handler): raise ServerException("'{0}' not found".format(handler.path)) class case_cgi_file(base_case): '''可執行腳本''' def run_cgi(self, handler): print('3333333') print(handler.full_path) print(type(handler.full_path)) #subprocess 就是一個相似cmd 的命令:感受跟os模塊os.system('python '+handler.full_path)同樣 #可是os.system運行後返回0,subprocess運行後返回運行結果.因此咱們用subprocess #data=os.system('python '+str(handler.full_path)) #print(data) #print(11111111111) data = subprocess.check_output(["python", handler.full_path],shell=False) print(66666666) print(data) handler.send_content(data) def test(self, handler): return os.path.isfile(handler.full_path) and \ handler.full_path.endswith('.py') def act(self, handler): self.run_cgi(handler) class case_existing_file(base_case): '''文件存在的狀況''' def test(self, handler): return os.path.isfile(handler.full_path) def act(self, handler): self.handle_file(handler, handler.full_path) class case_directory_index_file(base_case):#添加根目錄裏面index.html文件,這樣網頁打開就是這個 #index '''在根路徑下返回主頁文件''' def test(self, handler): print('什麼是handler') print(handler.full_path) #從這2個print知道handler就是RequestHandler的一個實例.這個框架自動設置好了 #handler就是RequestHandler的一個實例 return os.path.isdir(handler.full_path) and \ os.path.isfile(self.index_path(handler)) def act(self, handler): self.handle_file(handler, self.index_path(handler)) class case_always_fail(base_case): '''默認處理''' def test(self, handler): return True def act(self, handler): raise ServerException("Unknown object '{0}'".format(handler.path)) #先寫網絡主體:就是寫一個返回信息處理函數.必須繼承一個HTTPRequestHandler #這裏選擇BaseHTTPRequestHandler class RequestHandler(BaseHTTPRequestHandler): ''' 請求路徑合法則返回相應處理 不然返回錯誤頁面 ''' Error_Page = """\ <html> <body> <h1>Error accessing {path}</h1> <p>{msg}</p> </body> </html> """ Cases = [case_no_file(), case_cgi_file(), case_existing_file(), case_directory_index_file(), case_always_fail()] def do_GET(self):#名字必定是do_GET.GET請求自動觸發這個函數 try: # 獲得完整的請求路徑 print('path') print(self.path) #windows目錄有bug:須要把/改爲\ import re self.path= (re.sub(r'/', r'\\', self.path) ) print('pathnow') print(self.path) self.full_path = os.getcwd() + self.path print('什麼是self.full_path') print(self.full_path) # 遍歷全部的狀況並處理 for case in self.Cases: if case.test(self): case.act(self) break # 處理異常 except Exception as msg:#錯誤時候運行這下面的代碼,顯示出錯緣由 self.handle_error(msg) def handle_error(self, msg): # 錯誤頁面模板 content = self.Error_Page.format(path=self.path, msg=msg) self.send_content(content.encode("utf-8"), 404) # 發送數據到客戶端,#錯誤就調用content=error page 正確就調用content=index page #content裏面給html就夠了 def send_content(self, content, status=200):#這個函數把信息寫到網頁上 self.send_response(status) self.send_header("Content-type", "text/html") self.send_header("Content-Length", str(len(content))) self.end_headers() self.wfile.write(content) if __name__ == '__main__': serverAddress = ('', 8080) server = HTTPServer(serverAddress, RequestHandler) server.serve_forever()
功能:經過http.server模塊創建BaseHTTPRequestHandler的方法.利用subprocess模塊實現cgi編程,輸入time.py觀看當前時間.linux
補:由於windows目錄用\因此在linux上要作對應路徑的修改.上面程序是在windows上跑的.git
●用PIL.image,numpy經過歐式度量來對圖片進行馬賽克處理github
# coding:utf-8 """ 使用 Python 建立照片馬賽克 輸入一張目標照片和多張替換照片,將目標照片按網格劃分爲許多小方塊,而後將每一個小方塊替換爲顏色值最 接近的那張替換照片,就造成了馬賽克效果。 """ import argparse import os import numpy as np from PIL import Image def splitImage(image, size): """ 將圖像按網格劃分紅多個小圖像 @param {Image} image PIL Image 對象 @param {Tuple[int, int]} size 網格的行數和列數 @return {List[Image]} 小圖像列表 """ W, H = image.size[0], image.size[1] m, n = size w, h = int(W / n), int(H / m) imgs = [] # 先按行再按列裁剪出 m * n 個小圖像. # !!!也就是說只處理整除的那部分圖像,不整除剩下的邊角忽略了.也就是扔了 for j in range(m): for i in range(n): # 座標原點在圖像左上角 #crop函數帶的參數爲(起始點的橫座標,起始點的縱座標,終點的橫,終點的列) #這個網上有一些把crop的參數寫錯了.通過測試上面一行的說法是對的. imgs.append(image.crop((i * w, j * h, (i + 1) * w, (j + 1) * h))) return imgs def getImages(imageDir): """ 從給定目錄里加載全部替換圖像 @param {str} imageDir 目錄路徑 @return {List[Image]} 替換圖像列表 """ files = os.listdir(imageDir) images = [] for file in files: # 獲得文件絕對路徑 #爲了不出錯,這裏面用os.path.abspath來對路徑進行確認 filePath = os.path.abspath(os.path.join(imageDir, file)) try: fp = open(filePath, "rb")#貌似python 3裏面開文件都須要寫b.不寫b就出錯 im = Image.open(fp) #用image的方法打開,這樣存進去的就是圖片對象. images.append(im) # 肯定了圖像信息,但沒有加載所有圖像數據,用到時纔會 #把圖片load進內存,而後關閉文件便可.這樣操做更安全,若是下面3行不寫也同樣能跑. im.load() # 用完關閉文件,防止資源泄露 fp.close() except: #遇到某個圖片識別不了,read不出來直接跳過.少幾個不要緊 # 加載某個圖像識別,直接跳過 print("Invalid image: %s" % (filePath,)) return images def getAverageRGB(image): """ 計算圖像的平均 RGB 值 將圖像包含的每一個像素點的 R、G、B 值分別累加,而後除以像素點數,就獲得圖像的平均 R、G、B 值 @param {Image} image PIL Image 對象 @return {Tuple[int, int, int]} 平均 RGB 值 """ # 計算像素點數 npixels = image.size[0] * image.size[1] # 得到圖像包含的每種顏色及其計數,結果相似 [(cnt1, (r1, g1, b1)), ...] cols = image.getcolors(npixels) # 得到每種顏色的 R、G、B 累加值,結果相似 [(c1 * r1, c1 * g1, c1 * g2), ...] sumRGB = [(x[0] * x[1][0], x[0] * x[1][1], x[0] * x[1][2]) for x in cols] # 分別計算全部顏色的 R、G、B 平均值,算法相似(sum(ci * ri)/np, sum(ci * gi)/np, # sum(ci * bi)/np) # zip 的結果相似[(c1 * r1, c2 * r2, ..), (c1 * g1, c1 * g2, ...), (c1 * b1, # c1 * b2, ...)] avg = tuple([int(sum(x) / npixels) for x in zip(*sumRGB)])#用*解包.來組合結果很是經常使用的技巧 return avg def getAverageRGBNumpy(image):#是一個替換上面函數的方法,使用這個來計算比上面的快多了! """ 計算圖像的平均 RGB 值,使用 numpy 來計算以提高性能 @param {Image} image PIL Image 對象 @return {Tuple[int, int, int]} 平均 RGB 值 """ # 將 PIL Image 對象轉換爲 numpy 數據數組 im = np.array(image) # 得到圖像的寬、高和深度 w, h, d = im.shape # 將數據數組變形並計算平均值 #numpy轉化後的第三個座標取0就是r值!取1就是g取2就是b.很方便來計算rgb值 #.因此直接average便可. return tuple(np.average(im.reshape(w * h, d), axis=0)) def getBestMatchIndex(input_avg, avgs): """ 找出顏色值最接近的索引 把顏色值看作三維空間裏的一個點,依次計算目標點跟列表裏每一個點在三維空間裏的距離,從而獲得距 離最近的那個點的索引。 @param {Tuple[int, int, int]} input_avg 目標顏色值 @param {List[Tuple[int, int, int]]} avgs 要搜索的顏色值列表 @return {int} 命中元素的索引 """ #這函數是馬賽克算法的核心.就是找最接近的小圖給貼上.可是函數自己很簡單 index = 0 min_index = 0 min_dist = float("inf") for val in avgs: # 三維空間兩點距離計算公式 (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) # + (z1 - z2) * (z1 - z2),這裏只須要比較大小,因此無需求平方根值 dist = ((val[0] - input_avg[0]) * (val[0] - input_avg[0]) + (val[1] - input_avg[1]) * (val[1] - input_avg[1]) + (val[2] - input_avg[2]) * (val[2] - input_avg[2])) if dist < min_dist: min_dist = dist min_index = index index += 1 return min_index def createImageGrid(images, dims):#拼積木便可.先創立一個空白大圖像,小圖像挨個paste便可. """ 將圖像列表裏的小圖像按先行後列的順序拼接爲一個大圖像 @param {List[Image]} images 小圖像列表 @param {Tuple[int, int]} dims 大圖像的行數和列數 @return Image 拼接獲得的大圖像 """ m, n = dims # 確保小圖像個數知足要求 assert m * n == len(images) # 計算全部小圖像的最大寬度和高度 width = max([img.size[0] for img in images]) height = max([img.size[1] for img in images]) # 建立大圖像對象 grid_img = Image.new('RGB', (n * width, m * height)) # 依次將每一個小圖像粘貼到大圖像裏 for index in range(len(images)): # 計算要粘貼到網格的哪行 row = int(index / n) # 計算要粘貼到網格的哪列 col = index - n * row # 根據行列數以及網格的大小獲得網格的左上角座標,把小圖像粘貼到這裏 grid_img.paste(images[index], (col * width, row * height)) return grid_img def createPhotomosaic(target_image, input_images, grid_size, reuse_images=True): """ 圖片馬賽克生成 @param {Image} target_image 目標圖像 @param {List[Image]} input_images 替換圖像列表 @param {Tuple[int, int]} grid_size 網格行數和列數 @param {bool} reuse_images 是否容許重複使用替換圖像 @return {Image} 馬賽克圖像 """ # 將目標圖像切成網格小圖像 print('splitting input image...') target_images = splitImage(target_image, grid_size) # 爲每一個網格小圖像在替換圖像列表裏找到顏色最類似的替換圖像 print('finding image matches...') output_images = [] # 分 10 組進行,每組完成後打印進度信息,避免用戶長時間等待 count = 0 batch_size = int(len(target_images) / 10) # 計算替換圖像列表裏每一個圖像的顏色平均值 avgs = [] for img in input_images: #這裏用getAverageRGBNumpy果真變快了很多 avgs.append(getAverageRGBNumpy(img)) # 對每一個網格小圖像,從替換圖像列表找到顏色最類似的那個,添加到 output_images 裏 for img in target_images: # 計算顏色平均值 avg = getAverageRGB(img) # 找到最匹配的那個小圖像,添加到 output_images 裏 match_index = getBestMatchIndex(avg, avgs) output_images.append(input_images[match_index]) # 若是完成了一組,打印進度信息 if count > 0 and batch_size > 10 and count % batch_size == 0: print('processed %d of %d...' % (count, len(target_images))) count += 1 # 若是不容許重用替換圖像,則用事後就從列表裏移除,我感受這句話沒用.圖像確定要重複使用纔對. if not reuse_images: input_images.remove(match) # 將 output_images 裏的圖像按網格大小拼接成一個大圖像 print('creating mosaic...') mosaic_image = createImageGrid(output_images, grid_size) return mosaic_image def main(): #第一種控制程序的方式: ## 定義程序接收的命令行參數. ##用argparse模塊能夠在cmd中給這個.py的程序來加入參數來控制這個main()函數 #parser = argparse.ArgumentParser( #初始化一個分析器 # description='Creates a photomosaic from input images') #parser.add_argument('-target-image', dest='target_image', required=True) #parser.add_argument('--input-folder', dest='input_folder', required=True) #parser.add_argument('--grid-size', nargs=2, # dest='grid_size', required=True) #parser.add_argument('--output-file', dest='outfile', required=False) # 解析命令行參數 #args = parser.parse_args() #第二種控制參數方法:把參數傳給args類,我用這個方法吧.上面命令行不太會用 import os print(os.getcwd()) home=os.getcwd() print(home) class args(): grid_size=128,128 #切成128*128的小圖片 target_image=home+r'\test-data\a.jpg' #路徑要寫r,否則\識別不出來 input_folder=home+r'\test-data\set1' #馬賽克圖塊的目錄 outfile=home+r'\mosaiced.png' #馬賽克後的圖片保存目錄 print(args.target_image) print(type(home)) # 網格大小 grid_size = (int(args.grid_size[0]), int(args.grid_size[1])) print(grid_size) # 馬賽克圖像保存路徑,默認爲 mosaic.png output_filename = 'mosaic.png' if args.outfile: output_filename = args.outfile # 打開目標圖像 print('reading targe image...') print(args.target_image) target_image = Image.open(args.target_image) print(getAverageRGBNumpy(target_image)) print(00000000000000000) # 從指定文件夾下加載全部替換圖像 print('reading input images...') #看getImages怎麼寫.從一個文件夾讀入圖片.這個功能python沒有,本身寫一個 input_images = getImages(args.input_folder) # 若是替換圖像列表爲空則退出程序 if input_images == []: print('No input images found in %s. Exiting.' % (args.input_folder, )) exit() # 將全部替換圖像縮放到指定的網格大小 print('resizing images...') dims = (int(target_image.size[0] / grid_size[1]), int(target_image.size[1] / grid_size[0])) #dims表示最後的網格是幾乘幾的,若是不整除呢?這裏面就是除不開.dims是每個小圖片的尺寸 print(target_image.size)#看出圖片的大小是以像素爲單位的 print(dims) for img in input_images: img.thumbnail(dims) #thumbnail 對圖像進行縮小 # 生成馬賽克圖像 print('starting photomosaic creation...') mosaic_image = createPhotomosaic(target_image, input_images, grid_size) # 保存馬賽克圖像 mosaic_image.save(output_filename, 'PNG') print("saved output to %s" % (output_filename,)) print('done.') if __name__ == '__main__': main()
細節:image.crop image.paste來對文件進行裁剪粘貼成小塊.每個小塊用numpy轉化成矩陣獲得第三個維度的rgb值.正則表達式
對每個小塊找庫中純色小塊跟當前小塊3維歐式度量最近的小塊來替換當前小塊便可.
●用PIL模塊把圖片轉化成字符畫
from PIL import Image import argparse ##賦予參數的方法1:用argparse來設置命令行的參數用cmd python 文件.py +參數來運行 ##命令行輸入參數處理 #parser = argparse.ArgumentParser() #parser.add_argument('file') #輸入文件 #parser.add_argument('-o', '--output') #輸出文件 #parser.add_argument('--width', type = int, default = 80) #輸出字符畫寬 #parser.add_argument('--height', type = int, default = 80) #輸出字符畫高 ##獲取參數 #args = parser.parse_args() #我用第二個方法:直接在py裏面改 class args():#設置參數類 file =r'D:\桌面使用大全\repos\test-data\b.jpeg' width=50 height=50 output=r'D:\桌面使用大全\repos\test-data\char_b.txt' IMG = args.file WIDTH = args.width HEIGHT = args.height OUTPUT = args.output ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ") #解釋一下這個accii_char的構造:他實際上是一個灰度值表. #能夠用任意東西來替換裏面的內容.$就是表明灰度值最小的也就是亮度值最小的即黑色, #後面I1I''這些字符就是亮度值很大的接近白色的色塊.這個程序本質就是把原圖像素用這些字符替換便可. # 將256灰度映射到70個字符上 def get_char(r,g,b,alpha = 256): if alpha == 0: return ' ' length = len(ascii_char) gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b) # gray是灰度值獲得的數在0到255之間 unit = (256.0 + 1)/length #按比例轉化到70個字符上.也就是上面給的長list中的字符 return ascii_char[int(gray/unit)] if __name__ == '__main__': im = Image.open(IMG) im = im.resize((WIDTH,HEIGHT), Image.NEAREST) txt = "" for i in range(HEIGHT): for j in range(WIDTH):#im.getpixel((j,i))表示提取(j,i)位置的元素獲得一個(r,g,b)的tuple #把一個數組或者tuple賦值給一個函數get_char固然須要拆包語法* #也就是說他等價於他下面一句 txt += get_char(*im.getpixel((j,i))) #txt += get_char(im.getpixel((j,i))[0],im.getpixel((j,i))[1],im.getpixel((j,i))[2]) txt += '\n' print(txt) #字符畫輸出到文件 if OUTPUT: with open(OUTPUT,'w') as f: f.write(txt) else:#若是output參數不給就本身作一個output.txt #注意對生成的文件output觀看的時候用寫字板或者word,不要用記事本.由於他不會行對齊. with open("output.txt",'w') as f: f.write(txt)
●pyQt5實現簡單瀏覽器:前進後退刷新,打開多個網頁標籤功能.
from PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtWebKitWidgets import * import sys class MainWindow(QMainWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 設置窗口標題 self.resize(1200,800) self.setWindowTitle('My Browser') # 設置窗口圖標 self.setWindowIcon(QIcon('icons/penguin.png')) self.show() # 添加 URL 地址欄 self.urlbar = QLineEdit() # 讓地址欄能響應回車按鍵信號 self.urlbar.returnPressed.connect(self.navigate_to_url) # 添加標籤欄 self.tabs = QTabWidget() self.tabs.setDocumentMode(True) self.tabs.tabBarDoubleClicked.connect(self.tab_open_doubleclick) self.tabs.currentChanged.connect(self.current_tab_changed) self.tabs.setTabsClosable(True) self.tabs.tabCloseRequested.connect(self.close_current_tab) self.add_new_tab(QUrl('http://shiyanlou.com'), 'Homepage') self.setCentralWidget(self.tabs) # 添加導航欄 navigation_bar = QToolBar('Navigation') # 設定圖標的大小 navigation_bar.setIconSize(QSize(16, 16)) self.addToolBar(navigation_bar) # 添加前進、後退、中止加載和刷新的按鈕 back_button = QAction(QIcon('icons/back.png'), 'Back', self) next_button = QAction(QIcon('icons/next.png'), 'Forward', self) stop_button = QAction(QIcon('icons/cross.png'), 'stop', self) reload_button = QAction(QIcon('icons/renew.png'), 'reload', self) new_tab_action = QAction(QIcon('icons/add_page.png'), 'New Page', self) back_button.triggered.connect(self.tabs.currentWidget().back) next_button.triggered.connect(self.tabs.currentWidget().forward) stop_button.triggered.connect(self.tabs.currentWidget().stop) reload_button.triggered.connect(self.tabs.currentWidget().reload) new_tab_action.triggered.connect(self.tab_open_doubleclick) # 將按鈕添加到導航欄上 navigation_bar.addAction(back_button) navigation_bar.addAction(next_button) navigation_bar.addAction(stop_button) navigation_bar.addAction(reload_button) navigation_bar.addAction(new_tab_action) navigation_bar.addSeparator() navigation_bar.addWidget(self.urlbar) # 響應回車按鈕,將瀏覽器當前訪問的 URL 設置爲用戶輸入的 URL def navigate_to_url(self): q = QUrl(self.urlbar.text()) if q.scheme() == '': q.setScheme('http') self.tabs.currentWidget().setUrl(q) def renew_urlbar(self, q, browser=None): # 若是不是當前窗口所展現的網頁則不更新 URL if browser != self.tabs.currentWidget(): return # 將當前網頁的連接更新到地址欄 self.urlbar.setText(q.toString()) self.urlbar.setCursorPosition(0) # 添加新的標籤頁 def add_new_tab(self, qurl=QUrl(''), label='Blank'): # 爲標籤建立新網頁 browser = QWebView() browser.setUrl(qurl) i = self.tabs.addTab(browser, label) self.tabs.setCurrentIndex(i) browser.urlChanged.connect(lambda qurl, browser=browser: self.renew_urlbar(qurl, browser)) browser.loadFinished.connect(lambda _, i=i, browser=browser: self.tabs.setTabText(i, browser.page().mainFrame().title())) # 雙擊標籤欄打開新頁面 def tab_open_doubleclick(self, i): self.add_new_tab() # def current_tab_changed(self, i): qurl = self.tabs.currentWidget().url() self.renew_urlbar(qurl, self.tabs.currentWidget()) def close_current_tab(self, i): # 若是當前標籤頁只剩下一個則不關閉 if self.tabs.count() < 2: return self.tabs.removeTab(i) # 建立應用 app = QApplication(sys.argv) # 建立主窗口 window = MainWindow() # 顯示窗口 window.show() # 運行應用,並監聽事件 app.exec_()
●用dnn對汽車銷量這個比賽的代碼總結:
dnn加batch normalization
""" View more, visit my tutorial page: https://morvanzhou.github.io/tutorials/ My Youtube Channel: https://www.youtube.com/user/MorvanZhou Dependencies: torch: 0.1.11 matplotlib """ import torch from torch.autograd import Variable from torch import nn from torch.nn import init import torch.utils.data as Data import torch.nn.functional as F import matplotlib.pyplot as plt import numpy as np import torch from torch.autograd import Variable import torch.nn.functional as F import matplotlib.pyplot as plt # torch.manual_seed(1) # reproducible x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1) # x data (tensor), shape=(100, 1) y = x.pow(2) + 0.2*torch.rand(x.size()) # noisy y data (tensor), shape=(100, 1) # torch can only train on Variable, so convert them to Variable x, y = Variable(x), Variable(y) # plt.scatter(x.data.numpy(), y.data.numpy()) # plt.show() class Net(nn.Module): def __init__(self): super(Net, self).__init__() #對初始數據歸一化 self.dnn = nn.Sequential( nn.BatchNorm1d(1, momentum=0.5), # input shape (1, 28, 28) nn.Linear(1, 100), # if want same width and length of this image after con2d, padding=(kernel_size-1)/2 if stride=1 # output shape (16, 28, 28) #batchnormld的參數是上一層的輸出 nn.BatchNorm1d(100, momentum=0.5),# activation nn.ReLU(), nn.Linear(100, 10), # if want same width and length of this image after con2d, padding=(kernel_size-1)/2 if stride=1 # output shape (16, 28, 28) nn.BatchNorm1d(10, momentum=0.5),# activation nn.ReLU(), # choose max value in 2x2 area, output shape (16, 14, 14) nn.Linear(10, 1), ) def forward(self, x): x=self.dnn(x) return x net = Net() # define the network print(net) # net architecture optimizer = torch.optim.SGD(net.parameters(), lr=0.5) loss_func = torch.nn.MSELoss() # this is for regression mean squared loss plt.ion() # something about plotting for t in range(100): prediction = net(x) # input x and predict based on x loss = loss_func(prediction, y) # must be (1. nn output, 2. target) optimizer.zero_grad() # clear gradients for next train loss.backward() # backpropagation, compute gradients optimizer.step() # apply gradients if t % 5 == 0: # plot and show learning process plt.cla() plt.scatter(x.data.numpy(), y.data.numpy()) plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=5) plt.text(0.5, 0, 'Loss=%.4f' % loss.data[0], fontdict={'size': 20, 'color': 'red'}) plt.pause(0.1) plt.ioff() plt.show() #下面我寫一下輸出的效果.代碼幾乎都相同只差一個bn添加沒添加都只訓練100步,看loss大小 #第一次:不加bn:0.0628 加:0.0038 ## 第二次: 0.0568 加:0.0038
dnn手動加batch normalization
""" View more, visit my tutorial page: https://morvanzhou.github.io/tutorials/ My Youtube Channel: https://www.youtube.com/user/MorvanZhou Dependencies: torch: 0.1.11 matplotlib """ import torch from torch.autograd import Variable from torch import nn from torch.nn import init import torch.utils.data as Data import torch.nn.functional as F import matplotlib.pyplot as plt import numpy as np import torch from torch.autograd import Variable import torch.nn.functional as F import matplotlib.pyplot as plt # torch.manual_seed(1) # reproducible x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1) # x data (tensor), shape=(100, 1) y = x.pow(2) + 0.2*torch.rand(x.size()) # noisy y data (tensor), shape=(100, 1) # torch can only train on Variable, so convert them to Variable x, y = Variable(x), Variable(y) # plt.scatter(x.data.numpy(), y.data.numpy()) # plt.show() class Net(nn.Module): def __init__(self): super(Net, self).__init__() #對初始數據歸一化 self.diyi=nn.Linear(1, 100) self.dier=nn.Linear(100, 10) # if want same width and length of this image after con2d, padding=(kernel_size-1)/2 if stride=1 # output shape (16, 28, 28) #batchnormld的參數是上一層的輸出 self.diyi1=nn.ReLU() # choose max value in 2x2 area, output shape (16, 14, 14) self.disan=nn.Linear(10, 1) self.ui=nn.Linear(100,100) self.ui2=nn.Linear(10,10) def forward(self, x): m = torch.mean(x, dim=0)#計算均值 注意是在batch_size這個dim上作mean. std = torch.std(x, dim=0)#計算標準差 epsilon=0.0 #必須寫的足夠小才能歸一化,我寫0.01都不行,這個須要測試. x_normed = (x - m) / (std + epsilon)#歸一化 x=x_normed x=self.diyi(x) m = torch.mean(x, dim=0)#計算均值 注意是在batch_size這個dim上作mean. std = torch.std(x, dim=0)#計算標準差 epsilon=0.0 #必須寫的足夠小才能歸一化,我寫0.01都不行,這個須要測試. x_normed = (x - m) / (std + epsilon)#歸一化 x=x_normed x=self.ui(x) x=self.diyi1(x) x=self.dier(x) m = torch.mean(x, dim=0)#計算均值 注意是在batch_size這個dim上作mean. std = torch.std(x, dim=0)#計算標準差 epsilon=0.0 #必須寫的足夠小才能歸一化,我寫0.01都不行,這個須要測試. x_normed = (x - m) / (std + epsilon)#歸一化 x=x_normed x=self.ui2(x) x=self.diyi1(x) x=self.disan(x) return x net = Net() # define the network print(net) # net architecture optimizer = torch.optim.SGD(net.parameters(), lr=0.05) loss_func = torch.nn.MSELoss() # this is for regression mean squared loss plt.ion() # something about plotting for t in range(100): prediction = net(x) # input x and predict based on x loss = loss_func(prediction, y) # must be (1. nn output, 2. target) optimizer.zero_grad() # clear gradients for next train loss.backward() # backpropagation, compute gradients optimizer.step() # apply gradients if t % 5 == 0: # plot and show learning process plt.cla() plt.scatter(x.data.numpy(), y.data.numpy()) plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=5) plt.text(0.5, 0, 'Loss=%.4f' % loss.data[0], fontdict={'size': 20, 'color': 'red'}) plt.pause(0.1) plt.ioff() plt.show() #下面我寫一下輸出的效果.代碼幾乎都相同只差一個bn添加沒添加 #手動加沒寫明白,跑是跑了,效果這麼差? #後來通過個人改動,寫出來了,緣由就是SGD的理解不夠,他裏面第一個參數是 ## net.parameters(),他表示他只訓練網絡裏面的係數,這個係數指的是__init__裏面的係數 ## 不是forward裏面的係數,因此forward裏面的網絡除了歸一化之外的網絡都須要在__init__ ## 裏面先生成這個網絡模型,而後他的參數才能給SGD,而後才能進行學習, #效果差很少,手動寫的效果更好一點,多是由於個人學習率改更小了,說明學習率仍是很重要的 #即便你用了bn層也必定要調試好這個超參數
●實驗樓的用python寫2048
狀態機的使用和curses模塊來gui畫圖形和讀取鍵盤輸入.每個狀態轉移後就畫一次圖形.
curses:在python2.7環境下經過wheel來安裝.用anaconda能夠自動識別新裝入的2.7版本,而後打開2.7版本的終端來運行腳本便可.其實visual studio也
自動識別新安裝的python 環境,能夠在vs中切換.
#-*- coding:utf-8 -*- import curses from random import randrange, choice # generate and place new tile from collections import defaultdict letter_codes = [ord(ch) for ch in 'WASDRQwasdrq'] actions = ['Up', 'Left', 'Down', 'Right', 'Restart', 'Exit'] actions_dict = dict(zip(letter_codes, actions * 2)) def get_user_action(keyboard): char = "N" while char not in actions_dict: char = keyboard.getch() return actions_dict[char] def transpose(field): return [list(row) for row in zip(*field)] def invert(field): return [row[::-1] for row in field] class GameField(object): def __init__(self, height=4, width=4, win=2048): self.height = height self.width = width self.win_value = win self.score = 0 self.highscore = 0 self.reset() def reset(self): if self.score > self.highscore: self.highscore = self.score self.score = 0 self.field = [[0 for i in range(self.width)] for j in range(self.height)] self.spawn() self.spawn() def move(self, direction): def move_row_left(row): def tighten(row): # squeese non-zero elements together new_row = [i for i in row if i != 0] new_row += [0 for i in range(len(row) - len(new_row))] return new_row def merge(row): pair = False new_row = [] for i in range(len(row)): if pair: new_row.append(2 * row[i]) self.score += 2 * row[i] pair = False else: if i + 1 < len(row) and row[i] == row[i + 1]: pair = True new_row.append(0) else: new_row.append(row[i]) assert len(new_row) == len(row) return new_row return tighten(merge(tighten(row))) moves = {} moves['Left'] = lambda field: \ [move_row_left(row) for row in field] moves['Right'] = lambda field: \ invert(moves['Left'](invert(field))) moves['Up'] = lambda field: \ transpose(moves['Left'](transpose(field))) moves['Down'] = lambda field: \ transpose(moves['Right'](transpose(field))) if direction in moves: if self.move_is_possible(direction): self.field = moves[direction](self.field) self.spawn() return True else: return False def is_win(self): return any(any(i >= self.win_value for i in row) for row in self.field) def is_gameover(self): return not any(self.move_is_possible(move) for move in actions) def draw(self, screen): help_string1 = '(W)Up (S)Down (A)Left (D)Right' help_string2 = ' (R)Restart (Q)Exit' gameover_string = ' GAME OVER' win_string = ' YOU WIN!' def cast(string): screen.addstr(string + '\n') def draw_hor_separator(): line = '+' + ('+------' * self.width + '+')[1:] separator = defaultdict(lambda: line) if not hasattr(draw_hor_separator, "counter"): draw_hor_separator.counter = 0 cast(separator[draw_hor_separator.counter]) draw_hor_separator.counter += 1 def draw_row(row): cast(''.join('|{: ^5} '.format(num) if num > 0 else '| ' for num in row) + '|') screen.clear() cast('SCORE: ' + str(self.score)) if 0 != self.highscore: cast('HIGHSCORE: ' + str(self.highscore)) for row in self.field: draw_hor_separator() draw_row(row) draw_hor_separator() if self.is_win(): cast(win_string) else: if self.is_gameover(): cast(gameover_string) else: cast(help_string1) cast(help_string2) def spawn(self): new_element = 4 if randrange(100) > 89 else 2 (i,j) = choice([(i,j) for i in range(self.width) for j in range(self.height) if self.field[i][j] == 0]) self.field[i][j] = new_element def move_is_possible(self, direction): def row_is_left_movable(row): def change(i): # true if there'll be change in i-th tile if row[i] == 0 and row[i + 1] != 0: # Move return True if row[i] != 0 and row[i + 1] == row[i]: # Merge return True return False return any(change(i) for i in range(len(row) - 1)) check = {} check['Left'] = lambda field: \ any(row_is_left_movable(row) for row in field) check['Right'] = lambda field: \ check['Left'](invert(field)) check['Up'] = lambda field: \ check['Left'](transpose(field)) check['Down'] = lambda field: \ check['Right'](transpose(field)) if direction in check: return check[direction](self.field) else: return False def main(stdscr): def init(): #重置遊戲棋盤 game_field.reset() return 'Game' def not_game(state): #畫出 GameOver 或者 Win 的界面 game_field.draw(stdscr) #讀取用戶輸入獲得action,判斷是重啓遊戲仍是結束遊戲 action = get_user_action(stdscr) responses = defaultdict(lambda: state) #默認是當前狀態,沒有行爲就會一直在當前界面循環 responses['Restart'], responses['Exit'] = 'Init', 'Exit' #對應不一樣的行爲轉換到不一樣的狀態 return responses[action] def game(): #畫出當前棋盤狀態 game_field.draw(stdscr) #讀取用戶輸入獲得action action = get_user_action(stdscr) if action == 'Restart': return 'Init' if action == 'Exit': return 'Exit' if game_field.move(action): # move successful if game_field.is_win(): return 'Win' if game_field.is_gameover(): return 'Gameover' return 'Game' state_actions = { 'Init': init, 'Win': lambda: not_game('Win'), 'Gameover': lambda: not_game('Gameover'), 'Game': game } curses.use_default_colors() # 設置終結狀態最大數值爲 32 game_field = GameField(win=32) state = 'Init' #狀態機開始循環 while state != 'Exit': state = state_actions[state]() curses.wrapper(main)
●可能會用到的trie樹,dat樹,倒排索引
#coding=utf-8 #字典嵌套牛逼,別人寫的,這樣每一層很是多的東西,搜索就快了,樹高26.因此總體搜索一個不關多大的單詞表 #仍是O(1). ''' Python 字典 setdefault() 函數和get() 方法相似, 若是鍵不存在於字典中,將會添加鍵並將值設爲默認值。 說清楚就是:若是這個鍵存在字典中,那麼這句話就不起做用,不然就添加字典裏面這個key的取值爲後面的默認值. 簡化了字典計數的代碼.而且這個函數的返回值是作完這些事情以後這個key的value值. dict.setdefault(key, default=None) Python 字典 get() 函數返回指定鍵的值,若是值不在字典中返回默認值。 dict.get(key, default=None) ''' class Trie: root = {} END = '/' #加入這個是爲了區分單詞和前綴,若是這一層node裏面沒有/他就是前綴.不是咱們要找的單詞. def add(self, word): #從根節點遍歷單詞,char by char,若是不存在則新增,最後加上一個單詞結束標誌 node = self.root for c in word: node=node.setdefault(c,{}) #利用嵌套來作,一個trie樹的子樹也是一個trie樹. #利用setdefault的返回值是value的特性,若是找到了key就進入value #沒找到,就創建一個空字典而後 node[self.END] = None #當word都跑完了,就已經沒有字了.那麼當前節點也就是最後一個字母的節點 #加一個屬性標籤end.這個end裏面隨意放一個value便可.由於咱們斷定只是 #斷定end這個key是否在字典裏面. #考慮add 同一個單詞2次的狀況,第二次add 這個單詞的時候,由於用setdefault #add裏面的話都不對原字典進行修改.正好是咱們須要的效果. #這個self.END很重要,能夠做爲信息來存儲.好比裏面能夠輸入這個單詞的 #起源,發音,拼寫,詞組等做爲信息存進去.找這個單詞而後讀出單詞的信息. def find(self, word): node = self.root for c in word: if c not in node: return False node = node[c] return self.END in node def associate_find(self, pre): #搜索引擎裏面的功能是你輸入東西,不關是否是單詞,他都輸出以這個東西爲前綴 #的單詞. node = self.root for c in pre: if c not in node: return [] #由於字典裏面沒有pre這個前綴 node = node[c] #有這個前綴就繼續走,這裏有個問題就是須要記錄走過的路徑才行. #運行到這裏node就是最後一個字母所表示的字典. #舉一個栗子:圖形就是{a,b,c}裏面a的value是{b,c,d} d的value是{/,e,f} 那麼/表明的單詞就是ad,看這個形象多了 #首先看這個字母所在的字典有沒有END,返回a這個list #而後下面就是把前綴是pre的單詞都加到a裏面. #應該用廣度遍歷,深度遍歷重複計算太多了.好像深度也很方便,而且空間開銷很小. #廣度不行,每一次存入node,沒用的信息存入太多了.須要的信息只是這些key是什麼,而不須要存入node. #可是深度遍歷,又須要一個flag記錄每一個字母.字典的key又實現不了. #用函數遞歸來遍歷:只能先用這個效率最慢的先寫了 #由於你遍歷一直到底,到底必定是'/'和None.因此必定bianli出來的是單詞不是中間結果. def bianli(node):#返回node節點和他子節點拼出的全部單詞 if node==None: return [''] a=[]#如今node是/ef for i in node: tmp=node[i] tmp2=bianli(tmp) for j in tmp2: a.append(i+j) return a output=bianli(node) for i in range(len(output)): output[i]=(pre+output[i])[:-1] return output def delete(self, word):#字典中刪除word node = self.root for c in word: if c not in node: print('字典中沒有不用刪') return False node = node[c] #若是找到了就把'/'給他刪了就好了 del node['/'] #後面還須要檢索一遍,找一下是否有前綴的後面沒有單詞的.把前綴的最後一個字母也去掉.由於沒單詞了,前綴也沒意義存在了. #也就是說最後一個字母這個節點,只有'/',刪完若是是空的就把這個節點也刪了. while node=={}: if word=='': return tmp=word[-1] word=word[:-1] node = self.root for c in word: node = node[c] del node[tmp] a=Trie() (Trie.END)#python這個也是吊,類方法和類屬性:自動也是對象的方法或者屬性! a.add('apple') a.add('appl') a.delete('apple') print(a.find('apple')) print(a.root)#發現完美的解決了刪除功能.刪除apple由於沒有其餘單詞了就把整個字典刪了 #下面我打算加一個功能就是詞彙聯想功能,輸入a,輸出a,ab,abc.就是把a後面的字典裏面的全部的單詞就輸出出來. #兩個字典的key相同,id就相同.真坑.用id區分不了2個取值相同的不一樣元素. #my={'a':{}} #print(type(my)) #my['a']={'a':{'/'}} #for i in my: # print(id(i)) # a=my[i] # for j in a: # print(id(j))
''' ps:#a=[i*i for i in range(5) if i<3 ] #python for if 的一行寫法. https://segmentfault.com/a/1190000008877595#articleHeader7 5.4.2 Base Array 的構造 看這裏面寫的還真不難,以前一直沒看懂,是由於他數據沒有顯示寫入. 其實還有一個數組用來寫入數據.好比 這裏面第一步以後的data數組變成了 data[2]='清' data[3]='華' data[7]='中' 這樣經過他的步驟,作到最後就是3個數組,data,base,check3個數組來 表示這個2array trie.就能方便找到每個詞組了. 可是寫起來簡直吐血. 首先看最終獲得的結果如何使用它來找到全部的詞組: 字典:''清華」、「清華大學」、「清新」、「中華」、「華人」 編碼:清-1,華-2,大-3,學-4,新-5,中-6,人-7 數組下表:0 1 2 3 4 5 6 7 8 9 10 base數組:1 空 3 2 2 3 6 2 3 2 6 1.使用:找清華:首先從base[0]出發.清在的位置是base[0]+code(清)=下表爲2的地方 清的base數組不是負數,說明有繼續拓展的本事.因此找下一個詞華能夠找. 華=他上一個節點的base值+code(華)=3+2=5.因此就找到了清華在咱們字典裏面存在 找清華大學:上面華找到了,繼續找大=base(華)+code(大)=5(注意是清華的華,因此是上面找到的3)+3=6 繼續找學=base[6]+code(學)=10.因此清華大學找到了. 繼續細化:葉子節點的處理:將詞的最後一個節點的轉移基數統一改成某個負數 因此 數組下表:0 1 2 3 4 5 6 7 8 9 10 base數組:1 空 3 2 -2 -3 6 2 -3 -2 -6 這樣作的代價就是須要將狀態轉移函數base[s]+code(字符)改成|base[s]|+code(字符) 從新跑一次清華:上來仍是清=1+1=2 華=3+2=5 而後看base[5]=-3 ,因此能夠到此結束來組成一個詞彙. 可是咱們還能夠繼續跑 來找清華大學:從華找大:大=|-3|+code(大)=6,base[6]不是負數,不能輸出. 繼續找學:學=6+4=10,他的base是-6.因此能夠輸出. 加入check數組來解決bug:好比找'清中':找清咱們到了3,找中咱們到了9.base[9]=-2.因此咱們輸出'清中'是一個詞彙. 這顯然是錯誤的!因此咱們要加入check數組來避免這種匹配.這種bug的緣由是中這個詞前面 不能是清這個字.用check數組來記錄這個位置前面一個字符所在的index. 因此 數組下表:0 1 2 3 4 5 6 7 8 9 10 base數組:1 空 3 2 -2 -3 6 2 -3 -2 -6 check :-3 -1 0 0 7 2 5 0 2 3 6 這樣找清中:清是到了index2.判斷check是否是清的上一個節點.是0(0表示根)沒問題. 找中找到index9.而後須要判斷check[9]是否是他過來的節點的index.發現一個是2,一個是3 因此不對.輸出清中不存在. 2.搭建: https://blog.csdn.net/kissmile/article/details/47417277 這個寫的也是不錯.可是他搭建的順序有一點錯誤,按照層搭建,第五部分應該是搭建第一層的b後面的c節點. 邏輯基本就是這樣,能講清楚就不錯了.基本達到智商110以上了.能代碼實現感受智商上150了. 由於比較複雜,仍是先寫僞代碼.再實現. 題目:創建字典:字典:''清華」、「清華大學」、「清新」、「中華」、「華人」 僞代碼過程: ●a=[''清華」、「清華大學」、「清新」、「中華」、「華人」],b=sum([len(i) for i in a]) ●對set(a)進行編碼:清-1,華-2,大-3,學-4,新-5,中-6,人-7 ●創建首字集合c:清,中,華 ●爲了數組足夠長,創建base=[0]*b check=[0]*b ●把c插入雙數組,對base[0]賦予初值1.(其實賦予2也同樣,貌似更好,由於初值1基本都會發生衝突,會下降創建速度) 對新創建的base裏面也放入1. 把c插入後: 數組下表:0 1 2 3 4 5 6 7 8 9 10 base數組:1 0 1 1 0 0 0 1 0 0 0 check :0 0 0 0 0 0 0 0 0 0 0 ●下面就是插入第二個字:華,新,華,人(第一個華,表示清後面的華,雖然他有2個可是前面都是清,因此只插入一個,這就是爲何 Trie樹節省空間的緣由). 下面插入清後面的字:有華和新(對於同一個字的後面的字要一塊兒考慮,由於可能要修改這同一個的base數組) 從2開始跑,華=base[2]+code(華)=3.衝突了由於3裏面已經有了. 因此base[2]+=1.這時再算華=4了.不衝突了. 插入新又衝突了.因此清要繼續加1.插入後的新元素base仍是置1.(可是網上寫的是置清如今的base值.我感受不必啊!!!!) 也就是下圖5,8我都置1,可是網上置的是3.(下面經過個人計算,我置1最後仍是爲了解決衝突而加到3了. 難道置3能減小衝突的發生?問題是會不會空間浪費太多?)(利用樹來看就是樹的第n層的偏移量必定比第n-1層的至少同樣或者多) (爲何?)(我認爲是從機率上來說,每個字符邊上的字符數量都同樣,因此你上個字母須要偏移3個才能不衝突, 你也至少須要偏移3個.減小代碼運行時間.要知道處理衝突很是很是慢!!!!!) 同時把check也更新了,也就是把清的index 2放進去. 獲得: 數組下表:0 1 2 3 4 5 6 7 8 9 10 base數組:1 0 3 1 0 1 0 1 1 0 0 check : 0 0 0 0 0 2 0 0 2 0 0 (!!!!!!這裏面就是遇到一個問題很是重要.搭建時候必定要多行一塊兒搭建,也就是按照root的一層來搭建.把一層都弄好 再弄下一層,緣由就是咱們最後須要獲得的樹是一個公共前綴只保存一次的樹!也是問題的根本,不保持的話這個trie樹 徹底沒意義了,因此公共前綴保持同時處理,因此只能這樣按照root的層來搭建才能夠.) 同理插入中後面的字:7的base+=1.獲得: 數組下表:0 1 2 3 4 5 6 7 8 9 10 base數組:1 0 3 1 1 1 0 2 1 0 0 check : 0 0 0 0 7 2 0 0 2 0 0 同理華人:獲得: 數組下表:0 1 2 3 4 5 6 7 8 9 10 base數組:1 0 3 2 1 1 0 2 1 1 0 check : 0 0 0 0 7 2 0 0 2 3 0 第三層. 獲得: 數組下表:0 1 2 3 4 5 6 7 8 9 10 base數組:1 0 3 2 1 3 1 2 1 1 0 check : 0 0 0 0 7 2 5 0 2 3 0 第四層. 獲得: 數組下表:0 1 2 3 4 5 6 7 8 9 10 base數組:1 0 3 2 1 3 6 2 1 1 1 check : 0 0 0 0 7 2 5 0 2 3 6 總結:難度不比紅黑樹簡單. ''' class DAT(): def __init__(self,data):#經過這個函數返回self.base和self.check 2個數組 #對data預處理: firststep=[] max_ceng=0#數據有多少層 for i in data: a=0 for j in i: firststep.append(j) a+=1 if a>max_ceng: max_ceng=a all_len=len(firststep) mono_len=len(set(firststep)) #用字典進行編碼.用數組太慢了,由於數組裏面搜索是O(N) bianma={} ma=1 tmp=[] for i in firststep:#這裏面去重,爲了測試先這麼寫保順序,寫好後再改用set來加速 if i not in tmp: tmp.append(i) for i in tmp: if i not in bianma: bianma[i]=ma ma+=1 #我爲了方便把''做爲root,給他bianma 是0,而後base[0]=1 bianma['']=0#只是爲了遞歸寫起來代碼更簡潔而已.自我感受很簡約. #初始化base 和check base=['#']*all_len #雖然相同也不要用等號給check賦值base,由於list賦值是淺拷貝,傳的是地址 base[0]=1 check=['#']*all_len #打印一下編碼看看,由於字典是亂序的,每一次生成都不一樣,因此打印一下來驗算本身作的對不對. print(bianma) self.bianma=bianma #開始創建: #創建是按照第一列,...,最後一列這個順序進行遞歸的. #提取當前列的set後元素. #第一列能夠看作''空字符開始的後面一個元素. #提取第一列:而後再遞歸修改爲提取第i列 before='' col_now=[i[len(before)] for i in data if before in i]#提取有before前綴的字符的下一個小字符.#第一層就是清,華,中 tmp=[] for i in col_now: if i not in tmp: tmp.append(i) col_now=tmp print('第一列') print(col_now) #開始計算col_now裏面的字符的base before_index=bianma[before]#其餘層不是這麼算的. now_layer_save_for_data=[]#爲了下一層的遞推而記錄的文字信息 now_layer_save_for_base=[]#爲了下一層的遞推而記錄的index信息 for i in col_now: while 1: index=base[before_index]+bianma[i] if base[index]=='#':#說明沒有人佔用 base[index]=base[before_index] check[index]=before_index now_layer_save_for_data.append(i) now_layer_save_for_base.append(index) break else: base[before_index]+=1 last_layer=1 print('第一層') print(base)#測試後第一層創建成功. print(check) print(max_ceng) print(now_layer_save_for_data) print(now_layer_save_for_base) #仍是先寫遞推的寫法,遞歸的寫法想不清楚. #創建layer信息 layer1={} for i in range(len(data)): for jj in range(len(now_layer_save_for_data)): j=now_layer_save_for_data[jj] j2=now_layer_save_for_base[jj]#光用漢字來作key會發生沒法區分清華,中華這種bug. if data[i][0]==j: layer1.setdefault((j,j2),[]) layer1[(j,j2)].append(i) #用layer1,data裏面的信息,對base裏面信息進行加工,也就是若是單字就取反 for i in layer1: if i[0] in data: base[i[1]]=-base[i[1]] #搭建第二層:先找到將要被搭建的字 #利用last_layer和now_layer_save_for_data和now_layer_save_for_base來找. now_layer=last_layer+1 #for i in range(len(now_layer_save_for_data)): # tmp=now_layer_save_for_data[i]#tmp就是清 # id=now_layer_save_for_base[i]#id 就是清的base數組裏面的值 #找到清後面的字,也就是data裏面第一個字爲清的字.若是每創建一個節點就遍歷一遍會是至少O(N方),而且 #基本嚴格大於這個數字,太大了.我想法是一層的東西同時處理,這樣一層只遍歷一次.降到線性搜索. #對於同時一堆if,顯然效率不行,因此仍是字典來替代多if並列.仍是慢,想到用相似線段樹的手段來記錄. #裏面的每一層用一個字典來表示,一個value是一個list #根據layer1創建layer2 layer=layer1 print(layer) #下面就能夠創建layer2了#從這裏就能分析出爲何要把上一層有同一個前綴的都創建完再弄下一個. #下面整合起來是從一個layer獲得這個層的全base數組和check數組.能夠封裝起來for循環. for iii in range(1,max_ceng): now_layer=iii+1 layer4={} print(layer) #layer1:{('清', 2): [0, 1, 2], ('中', 7): [3], ('華', 3): [4]} for i in layer: lastword=i[0] lastindex=i[1] beixuan=layer[i] #找到應該插入哪一個 charu=[] #把beixuan裏面長度不夠的剔除,他長度不夠其實就表示已經在上一步是詞組了. beixuan2=[] for i in beixuan : if len(data[i])>=now_layer: beixuan2.append(i) beixuan=beixuan2 for i in beixuan: newword=data[i][now_layer-1] if newword not in charu: charu.append(newword) #把charu裏面的東西進入base,check算法中 now_layer_save_for_data=[]#爲了下一層的遞推而記錄的文字信息 now_layer_save_for_base=[]#爲了下一層的遞推而記錄的index信息 col_now=charu #插入華,新 before_index=abs(lastindex) for i in col_now: while 1: index=abs(base[before_index])+bianma[i] if base[index]=='#':#說明沒有人佔用 break else: if base[before_index]>0: base[before_index]+=1 else: base[before_index]-=1 print(base) #對於已經構成詞彙的詞語base裏面的數要取相反數. beixuanciku=[data[i][now_layer-1:] for i in beixuan] #調試狀態vs2017把鼠標放變量上就能看到他的取值,很放方便.任意位置都能看 for i in col_now: if i in beixuanciku: index=abs(base[before_index])+bianma[i] base[index]=-abs(base[before_index])#注意這地方不能寫-要寫-abs check[index]=before_index now_layer_save_for_data.append(i) now_layer_save_for_base.append(index) else: index=abs(base[before_index])+bianma[i] base[index]=base[before_index] check[index]=before_index now_layer_save_for_data.append(i) now_layer_save_for_base.append(index) #更新layer for i in beixuan: for jj in range(len(now_layer_save_for_data)): j=now_layer_save_for_data[jj] j2=now_layer_save_for_base[jj]#光用漢字來作key會發生沒法區分清華,中華這種bug. if data[i][now_layer-1]==j: layer4.setdefault((j,j2),[]) layer4[(j,j2)].append(i) #已經獲得了新的layer4,替換回去,爲了遞推. layer=layer4 #打印上個layer print(layer) #{('清', 2): [0, 1, 2], ('中', 7): [3], ('華', 3): [4]} 上個layeer信息 #下面須要更新layer layernew={} for i in layer:#逐個計算裏面的對兒便可.好比先計算('清', 2): [0, 1, 2]應該改爲什麼 pass #for jj in range(len(now_layer_save_for_data)): # j=now_layer_save_for_data[jj] # j2=now_layer_save_for_base[jj]#光用漢字來作key會發生沒法區分清華,中華這種bug. # if data[i][0]==j: # layer1.setdefault((j,j2),[]) # layer1[(j,j2)].append(i) print(now_layer_save_for_data) print(now_layer_save_for_base) print('測試')#第二列也zhengque #通過我2天超過20個小時的學習和寫代碼,寫出了這個例子的base數組和check數組.修改些小bug就能夠了. #絕逼不比紅黑樹簡單.網上也幾乎沒有代碼實現.由於我主題layer是從第一層創建後針對2到n層開始創建的 #因此第一層若是是單字,直接返回這種狀況,我還沒寫,可是相對蓋起來簡單. print(base) print(check) #最後的最後,用self把結果傳出去 self.base=base self.check=check def search(self,a):#經過這個函數a在data是否存在,這個函數隨便玩了 tmp=0 #self寫起來太麻煩, bianma=self.bianma base=self.base check=self.check i=a[0] if len(a)==1: tmp=1+bianma[i] return base[tmp]<0 else: first=1+bianma[a[0]] for i in range(len(a)-1): tmp=abs(base[first])+bianma[a[i+1]] if check[tmp]!=first: return False first=tmp return base[tmp]<0 ''' base:[1, '#', -3, 2, -2, -3, -6, 2, -3, -2, -6, '#', '#'] check:['#', '#', 0, 0, 7, 2, 5, 0, 2, 3, 6, '#', '#'] ''' #測試: a=DAT(['清華','清華大學','清新','中華','華人','清']) #進行search測試 print(a.search('清華大學')) #通過測試,稍微大一點的數據也是能跑出來的.
''' 倒排索引:https://blog.csdn.net/okiwilldoit/article/details/51362839 ''' ''' 先學分詞系統jieba:pip install jieba便可. ''' import jieba s = u'我想和我女友一塊兒去個人北京故宮博物院參觀個人屋子和閒逛。' cut = jieba.cut(s) print ('output') print (cut) #返回的是一個迭代器.這對大數據很叼.個人理解是由於 #迭代器能夠隨時暫停,而後恢復繼續上面的工做繼續迭代 #數據太大也能夠跑跑停停不用一直等,能夠隨時看結果 print (','.join(cut))#竟然花了10秒! 精準模式.也是最經常使用的,第二次跑有cache就用了0.8s print (','.join(jieba.cut(s,cut_all = True)))#可見全模式就是把文本分紅儘量多的詞。 print (','.join(jieba.cut_for_search(s)))#搜索引擎模式介於上面2者中間 #import jieba.posseg as psg ##下面一行返回的是分詞後各個詞性 ##print ([(x.word,x.flag) for x in psg.cut(s)])#x是字符串的意思,這一行太卡了我就註釋掉了, #from collections import Counter#利用Counter這個容器能夠返回頻率top多少的詞,可是速度很慢. #c = Counter(s).most_common(20) #print (c) ##下面學習用戶字典: #txt = u'歐陽建國是創新辦主任也是歡聚時代公司雲計算方面的專家' #print (','.join(jieba.cut(txt))) #jieba.load_userdict('user_dict.txt')#注意這個詞典,在同目錄下,而後編碼用筆記本打開另存爲utf-8便可. #print (','.join(jieba.cut(txt)))#效果不錯 ''' 下面能夠進行倒排索引了 ''' #不要的虛詞: _STOP_WORDS = frozenset([ 'a', 'about', 'above', 'above', 'across', 'after', 'afterwards', 'again', 'against', 'all', 'almost', 'alone', 'along', 'already', 'also', 'although', 'always', 'am', 'among', 'amongst', 'amoungst', 'amount', 'an', 'and', 'another', 'any', 'anyhow', 'anyone', 'anything', 'anyway', 'anywhere', 'are', 'around', 'as', 'at', 'back', 'be', 'became', 'because', 'become', 'becomes', 'becoming', 'been', 'before', 'beforehand', 'behind', 'being', 'below', 'beside', 'besides', 'between', 'beyond', 'bill', 'both', 'bottom', 'but', 'by', 'call', 'can', 'cannot', 'cant', 'co', 'con', 'could', 'couldnt', 'cry', 'de', 'describe', 'detail', 'do', 'done', 'down', 'due', 'during', 'each', 'eg', 'eight', 'either', 'eleven', 'else', 'elsewhere', 'empty', 'enough', 'etc', 'even', 'ever', 'every', 'everyone', 'everything', 'everywhere', 'except', 'few', 'fifteen', 'fify', 'fill', 'find', 'fire', 'first', 'five', 'for', 'former', 'formerly', 'forty', 'found', 'four', 'from', 'front', 'full', 'further', 'get', 'give', 'go', 'had', 'has', 'hasnt', 'have', 'he', 'hence', 'her', 'here', 'hereafter', 'hereby', 'herein', 'hereupon', 'hers', 'herself', 'him', 'himself', 'his', 'how', 'however', 'hundred', 'ie', 'if', 'in', 'inc', 'indeed', 'interest', 'into', 'is', 'it', 'its', 'itself', 'keep', 'last', 'latter', 'latterly', 'least', 'less', 'ltd', 'made', 'many', 'may', 'me', 'meanwhile', 'might', 'mill', 'mine', 'more', 'moreover', 'most', 'mostly', 'move', 'much', 'must', 'my', 'myself', 'name', 'namely', 'neither', 'never', 'nevertheless', 'next', 'nine', 'no', 'nobody', 'none', 'noone', 'nor', 'not', 'nothing', 'now', 'nowhere', 'of', 'off', 'often', 'on', 'once', 'one', 'only', 'onto', 'or', 'other', 'others', 'otherwise', 'our', 'ours', 'ourselves', 'out', 'over', 'own', 'part', 'per', 'perhaps', 'please', 'put', 'rather', 're', 'same', 'see', 'seem', 'seemed', 'seeming', 'seems', 'serious', 'several', 'she', 'should', 'show', 'side', 'since', 'sincere', 'six', 'sixty', 'so', 'some', 'somehow', 'someone', 'something', 'sometime', 'sometimes', 'somewhere', 'still', 'such', 'system', 'take', 'ten', 'than', 'that', 'the', 'their', 'them', 'themselves', 'then', 'thence', 'there', 'thereafter', 'thereby', 'therefore', 'therein', 'thereupon', 'these', 'they', 'thickv', 'thin', 'third', 'this', 'those', 'though', 'three', 'through', 'throughout', 'thru', 'thus', 'to', 'together', 'too', 'top', 'toward', 'towards', 'twelve', 'twenty', 'two', 'un', 'under', 'until', 'up', 'upon', 'us', 'very', 'via', 'was', 'we', 'well', 'were', 'what', 'whatever', 'when', 'whence', 'whenever', 'where', 'whereafter', 'whereas', 'whereby', 'wherein', 'whereupon', 'wherever', 'whether', 'which', 'while', 'whither', 'who', 'whoever', 'whole', 'whom', 'whose', 'why', 'will', 'with', 'within', 'without', 'would', 'yet', 'you', 'your', 'yours', 'yourself', 'yourselves', 'the']) import os import jieba import re import sys def word_index(text): words = word_split(text) words = words_cleanup(words) return words def word_split(text): word_list = [] pattern = re.compile(u'[\u4e00-\u9fa5]+')#提取中文,unicode編碼\u4e00-\u9fa5的一個或者多個字符. jieba_list = list(jieba.cut(text)) time = {} for c in (jieba_list): if c in time: # record appear time time[c] += 1 else: time.setdefault(c, 0) #time第一次設爲0是python本身語法這麼定的, #text.index(c,t)返回text中c出現第t+1次的index.語法就是這麼奇怪. #因此time裏面寫i表示這個單詞出現i+1次, if pattern.search(c): # if Chinese word_list.append((len(word_list), (text.index(c, time[c]), c))) continue if c.isalnum(): # if English or number word_list.append((len(word_list), (text.index(c, time[c]), c.lower()))) # include normalize return word_list #先作單詞的預處理,把上面分好的word_list給words_cleanup作篩選 def words_cleanup(words): #index 是單詞在word_list中編號,offset是單詞在text中下標,word就是單詞. cleaned_words = [] for index, (offset, word) in words: # words-(word index for search,(letter offset for display,word)) if word in _STOP_WORDS: continue cleaned_words.append((index, (offset, word))) return cleaned_words def inverted_index(text): words = word_split(text) words = words_cleanup(words) inverted = {} for index, (offset, word) in words:#words就是洗完的數據. locations = inverted.setdefault(word, [])#把洗完的數據根據word從新歸類.同一個word放一塊兒 locations.append((index, offset)) return inverted #最後獲得的就是倒查索引的結果這個字典.value是 第幾個次,偏移量(text裏面下標) a=inverted_index('路上看到就發了開始的路路路路路路路')#a是倒排索引的字典,下面給這個字典加幾個功能.都很簡單 #對倒排索引繼續添加功能:這個功能是把舊的inverted倒排字典跟新的doc_index倒排字典作合併. #下面的方法就是繼續加了一層索引是doc_id.這樣倒排索引變成了 #key:word value:{doc_id1,....doc_idn} 而後每個doc_idi對應一個列表 #列表中每一項是(index,offset) 這樣就作成了一個完善的多文件系統中找關鍵字的位置的倒排索引 #使用的時候只須要從inverted={},用inverted_index_add往裏面加便可. def inverted_index_add(inverted, doc_id, doc_index): for word, locations in doc_index.items(): indices = inverted.setdefault(word, {}) indices[doc_id] = locations return inverted from functools import reduce def search(inverted, query): word = [word for _ , (offset, word) in word_index(query) if word in inverted][0] doc_set=inverted[word].keys() #doc_set 獲得的是全部含query這個單詞的文件編號. output=[] if doc_set: for doc in doc_set:#遍歷全部的有效文檔 for a in inverted[word][doc]: #打印一點word左邊的字符和右邊的字符 output.append((doc,a[0],word)) return output inverted={} doc_index = inverted_index('我個人個人是個人個人') a=inverted_index_add(inverted, 1, doc_index) doc_index = inverted_index('我想和我女友一塊兒去個人北京故宮博物院參觀個人屋子和閒逛') b=inverted_index_add(inverted, 2, doc_index) print(inverted) print(search(inverted,'我')) #結果:[(1, 0, '我'), (1, 1, '我'), (1, 3, '我'), (1, 6, '我'), (1, 8, '我'), (2, 0, '我'), (2, 3, '我'), (2, 7, '我'), (2, 11, '我')] #表示第一個文章第0個字符是我...............這樣就作到了搜索引擎.給一個字或者詞,他會返回他 #所在的哪篇文章中的第幾個字符. #具體還須要加入搜索結果的優先級.這樣優先級高的寫在前面給用戶看.簡單排序便可.實現.
●實驗樓的識別驗證碼
#-*- coding:utf8 -*- from PIL import Image import numpy as np im = Image.open("captcha.gif") #(將圖片轉換爲8位像素模式) im.convert("L") #打印顏色直方圖 print (im.histogram()) his = im.histogram() values = {} for i in range(256): values[i] = his[i] for j,k in sorted(values.items(),key=lambda x:x[1],reverse = True)[:10]: print (j,k) #-*- coding:utf8 -*- from PIL import Image #下面是去噪.若是不知道須要的顏色是220和227怎麼辦? im = Image.open("captcha.gif") im.convert("P") a=np.array(im) im2 = Image.new("P",im.size,255) for x in range(im.size[1]): for y in range(im.size[0]): pix = im.getpixel((y,x)) if pix == 220 or pix == 227: # these are the numbers to get im2.putpixel((y,x),0) a=np.array(im2) print(a.shape) #注意圖片處理的長和寬: #im2.size=多少個列*多少個行 a.shape=圖片多少個行*多少個列 正好反過來! inletter = False foundletter=False start = 0 end = 0 letters = [] #print(9999999) #print(list(im2.getdata()))#返回像素值序列 #print(im2.size) for y in range(im2.size[0]): inletter=False for x in range(im2.size[1]): pix = im2.getpixel((y,x)) if pix != 255: inletter = True if foundletter == False and inletter == True: foundletter = True start = y if foundletter == True and inletter == False: foundletter = False end = y letters.append((start,end)) #最後獲得的切分是im[start:end]即:不包含隨後end列 from PIL import Image import hashlib import time import os import math class VectorCompare: def magnitude(self,concordance): total = 0 for word,count in concordance.items(): total += count ** 2 return math.sqrt(total) def relation(self,concordance1, concordance2): relevance = 0 topvalue = 0 for word, count in concordance1.items(): if (word) in concordance2: topvalue += count * concordance2[word] #返回一個cos值.值越大就說明越接近.越小就說明夾角越趨近90度,不相關. return topvalue / (self.magnitude(concordance1) * self.magnitude(concordance2)) def buildvector(im): d1 = {} count = 0 for i in im.getdata(): d1[count] = i count += 1 return d1 v = VectorCompare() iconset = ['0','1','2','3','4','5','6','7','8','9','0','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'] imageset = [] for letter in iconset: for img in os.listdir('./iconset/%s/'%(letter)): temp = [] if img != "Thumbs.db" and img != ".DS_Store": # windows check... temp.append(buildvector(Image.open("./iconset/%s/%s"%(letter,img)))) imageset.append({letter:temp})#創建了不少個字典,每個案例圖片創建一個字典,這些字典都只有一個key,值 #是一個數組,數組裏面只有一個數據,一個buildvector函數的返回值一個字典.寫這麼多嵌套搞毛 for letter in letters: m = hashlib.md5() im3 = im2.crop(( letter[0] , 0, letter[1],im2.size[1] )) #im3是單個字符 guess = [] for image in imageset: for x,y in image.items(): guess.append(( v.relation(y[0],buildvector(im3)),x) ) guess.sort(reverse=True) print ("",guess[0])
●莫凡教python的pytorch課程:
作迴歸:
import torch import matplotlib.pyplot as plt #unsqueeze加一維,加dim=1.加一維到dim=1.因此把100的數組變成100*1的數組 x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1) # x data (tensor), shape=(100, 1) y = x**2 + 0.2*torch.rand(x.size()) # noisy y data (tensor), shape=(100, 1) # 畫圖 #plt.scatter(x.data.numpy(), y.data.numpy()) #plt.show() import torch import torch.nn.functional as F # 激勵函數都在這 class Net(torch.nn.Module): # 繼承 torch 的 Module def __init__(self, n_feature, n_hidden, n_output): super(Net, self).__init__() # 繼承 __init__ 功能 # 定義每層用什麼樣的形式 self.hidden = torch.nn.Linear(n_feature, n_hidden) # 隱藏層線性輸出 self.predict = torch.nn.Linear(n_hidden, n_output) # 輸出層線性輸出 def forward(self, x): # 這同時也是 Module 中的 forward 功能 # 正向傳播輸入值, 神經網絡分析出輸出值 x = F.relu(self.hidden(x)) # 激勵函數(隱藏層的線性值) x = self.predict(x) # 輸出值 return x net = Net(n_feature=1, n_hidden=10, n_output=1) print(net) # net 的結構 """ Net ( (hidden): Linear (1 -> 10) (predict): Linear (10 -> 1) ) """ # optimizer 是訓練的工具 optimizer = torch.optim.SGD(net.parameters(), lr=0.2) # 傳入 net 的全部參數, 學習率 loss_func = torch.nn.MSELoss() # 預測值和真實值的偏差計算公式 (均方差) for t in range(100): prediction = net(x) # 餵給 net 訓練數據 x, 輸出預測值 loss = loss_func(prediction, y) # 計算二者的偏差 optimizer.zero_grad() # 清空上一步的殘餘更新參數值 loss.backward() # 偏差反向傳播, 計算參數更新值 optimizer.step() # 將參數更新值施加到 net 的 parameters 上 #畫圖 if t % 5 == 0: # plot and show learning process plt.cla() plt.scatter(x.data.numpy(), y.data.numpy()) plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=5) plt.text(0.5, 0, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 20, 'color': 'red'}) plt.pause(0.1) plt.ion() # 畫圖,連續的畫圖,因此就是輸出一個動畫 plt.show()
分類:
import torch import matplotlib.pyplot as plt import matplotlib.pyplot as plt # 假數據 n_data = torch.ones(100, 2) # 數據的基本形態 x0 = torch.normal(2*n_data, 1) # 類型0 x data (tensor), shape=(100, 2) y0 = torch.zeros(100) # 類型0 y data (tensor), shape=(100, 1) x1 = torch.normal(-2*n_data, 1) # 類型1 x data (tensor), shape=(100, 2) y1 = torch.ones(100) # 類型1 y data (tensor), shape=(100, 1) # 注意 x, y 數據的數據形式是必定要像下面同樣 (torch.cat 是在合併數據) x = torch.cat((x0, x1), ).type(torch.FloatTensor) # FloatTensor = 32-bit floating y = torch.cat((y0, y1), ).type(torch.LongTensor) # LongTensor = 64-bit integer import torch import torch.nn.functional as F # 激勵函數都在這 class Net(torch.nn.Module): # 繼承 torch 的 Module def __init__(self, n_feature, n_hidden, n_output): super(Net, self).__init__() # 繼承 __init__ 功能 self.hidden = torch.nn.Linear(n_feature, n_hidden) # 隱藏層線性輸出 self.out = torch.nn.Linear(n_hidden, n_output) # 輸出層線性輸出 def forward(self, x): # 正向傳播輸入值, 神經網絡分析出輸出值 x = F.relu(self.hidden(x)) # 激勵函數(隱藏層的線性值) x = self.out(x) # 輸出值, 可是這個不是預測值, 預測值還須要再另外計算 return x net = Net(n_feature=2, n_hidden=10, n_output=2) # 幾個類別就幾個 output print(net) # net 的結構 """ Net ( (hidden): Linear (2 -> 10) (out): Linear (10 -> 2) ) """ # optimizer 是訓練的工具 optimizer = torch.optim.SGD(net.parameters(), lr=0.02) # 傳入 net 的全部參數, 學習率 # 算偏差的時候, 注意真實值!不是! one-hot 形式的, 而是1D Tensor, (batch,) # 可是預測值是2D tensor (batch, n_classes) loss_func = torch.nn.CrossEntropyLoss() plt.ion() # 畫圖#這種開始連續畫圖,關閉連續畫圖都扔學習for循環的外面 for t in range(100): out = net(x) # 餵給 net 訓練數據 x, 輸出分析值 loss = loss_func(out, y) # 計算二者的偏差 optimizer.zero_grad() # 清空上一步的殘餘更新參數值 loss.backward() # 偏差反向傳播, 計算參數更新值 optimizer.step() # 將參數更新值施加到 net 的 parameters 上 #下面是畫圖 # 接着上面來 if t % 2 == 0: plt.cla() # 過了一道 softmax 的激勵函數後的最大機率纔是預測值 prediction = torch.max(F.softmax(out), 1)[1] pred_y = prediction.data.numpy().squeeze() target_y = y.data.numpy() plt.scatter(x.data.numpy()[:, 0], x.data.numpy()[:, 1], c=pred_y, s=100, lw=0, cmap='RdYlGn') accuracy = sum(pred_y == target_y)/200. # 預測中有多少和真實值同樣 plt.text(1.5, -4, 'Accuracy=%.2f' % accuracy, fontdict={'size': 20, 'color': 'red'}) plt.pause(0.1) plt.show() plt.ioff() # 中止畫圖# 畫圖#這種開始連續畫圖,關閉連續畫圖都扔學習for循環的外面 plt.show() #爲了最後停下來,仍顯示圖片.因此繼續寫一個show
保存整個網絡
import torch torch.manual_seed(1) # reproducible # 假數據 x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1) # x data (tensor), shape=(100, 1) y = x.pow(2) + 0.2*torch.rand(x.size()) # noisy y data (tensor), shape=(100, 1) def save(): # 建網絡 net1 = torch.nn.Sequential( torch.nn.Linear(1, 10), torch.nn.ReLU(), torch.nn.Linear(10, 1) ) optimizer = torch.optim.SGD(net1.parameters(), lr=0.5) loss_func = torch.nn.MSELoss() # 訓練 for t in range(100): prediction = net1(x) loss = loss_func(prediction, y) optimizer.zero_grad() loss.backward() optimizer.step() torch.save(net1, 'net.pkl') # 保存整個網絡 net2=0 def restore_net(): # restore entire net1 to net2 global net2 net2 = torch.load('net.pkl') prediction = net2(x) # 保存 net1 ( 整個網絡) save() # 提取整個網絡 restore_net() print(net2)
保存網絡的參數就能重建網絡
import torch torch.manual_seed(1) # reproducible # 假數據 x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1) # x data (tensor), shape=(100, 1) y = x.pow(2) + 0.2*torch.rand(x.size()) # noisy y data (tensor), shape=(100, 1) def save(): # 建網絡 net1 = torch.nn.Sequential( torch.nn.Linear(1, 10), torch.nn.ReLU(), torch.nn.Linear(10, 1) ) optimizer = torch.optim.SGD(net1.parameters(), lr=0.5) loss_func = torch.nn.MSELoss() # 訓練 for t in range(100): prediction = net1(x) loss = loss_func(prediction, y) optimizer.zero_grad() loss.backward() optimizer.step() torch.save(net1.state_dict(), 'net_params.pkl') # 只保存網絡中的參數 (速度快, 佔內存少) net3=0 def restore_params(): # 新建 net3 global net3#重建的時候須要從新寫一下網絡的結構.因此這種記錄參數的方法速度快,可是須要寫的代碼多一點. net3 = torch.nn.Sequential( torch.nn.Linear(1, 10), torch.nn.ReLU(), torch.nn.Linear(10, 1) ) # 將保存的參數複製到 net3 net3.load_state_dict(torch.load('net_params.pkl')) prediction = net3(x) # 保存 net1 ( 整個網絡) save() # 提取整個網絡 restore_params() print(net3)
batch訓練模板的使用
#這個是torch 0.4版本的代碼跟莫凡講的有點不一樣,由於他的是舊版本. #利用這個Data.TensorDataset結構來封裝訓練數據x,y以後只須要設置BATCH_SIZE便可. #不用手動分組shuffle了.而且若是batch_size不被數據個數整除,那麼就自動會在最後一組放入所有剩餘數據. #這也就是咱們須要的效果 if __name__=='__main__': import torch import torch.utils.data as Data torch.manual_seed(1) # reproducible BATCH_SIZE = 8 # 批訓練的數據個數 x = torch.linspace(1, 10, 10) # x data (torch tensor) y = torch.linspace(10, 1, 10) # y data (torch tensor) # 先轉換成 torch 能識別的 Dataset torch_dataset = Data.TensorDataset(x, y) # 把 dataset 放入 DataLoader loader = Data.DataLoader( dataset=torch_dataset, # torch TensorDataset format batch_size=BATCH_SIZE, # mini batch size shuffle=True, # 要不要打亂數據 (打亂比較好) num_workers=2, # 多線程來讀數據 ) for epoch in range(3): # 訓練全部!整套!數據 3 次 for step, (batch_x, batch_y) in enumerate(loader): # 每一步 loader 釋放一小批數據用來學習 # 假設這裏就是你訓練的地方... #這裏就暫時空白了,須要用的時候寫上訓練步奏便可. # 打出來一些數據 print('Epoch: ', epoch, '| Step: ', step, '| batch x: ', batch_x.numpy(), '| batch y: ', batch_y.numpy())
cnn跑mnist
import torch import torch.nn as nn import torch.utils.data as Data import torchvision # 數據庫模塊 import matplotlib.pyplot as plt torch.manual_seed(1) # reproducible # Hyper Parameters EPOCH = 1 # 訓練整批數據多少次, 爲了節約時間, 咱們只訓練一次 BATCH_SIZE = 50 LR = 0.001 # 學習率 DOWNLOAD_MNIST = False # 若是你已經下載好了mnist數據就寫上 Fasle,下載完就改False便可 #下載數據 # Mnist 手寫數字 #下載train data train_data = torchvision.datasets.MNIST( root='./mnist/', # 保存或者提取位置 train=True, # this is training data transform=torchvision.transforms.ToTensor(), # 轉換 PIL.Image or numpy.ndarray 成 # torch.FloatTensor (C x H x W), 訓練的時候 normalize 成 [0.0, 1.0] 區間 download=DOWNLOAD_MNIST, # 沒下載就下載, 下載了就不用再下了 ) #下載test data test_data = torchvision.datasets.MNIST(root='./mnist/', train=False) # 批訓練 50samples, 1 channel, 28x28 (50, 1, 28, 28) train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True) # 爲了節約時間, 咱們測試時只測試前2000個 test_x = torch.unsqueeze(test_data.test_data, dim=1).type(torch.FloatTensor)[:2000]/255. # shape from (2000, 28, 28) to (2000, 1, 28, 28), value in range(0,1) test_y = test_data.test_labels[:2000] print(test_y) #wangluo class CNN(nn.Module): def __init__(self): super(CNN, self).__init__() #數據進來就 卷積,relu,池化,卷積,relu,池化,就完了.最後的全鏈接層爲了讓最後輸出10個數 self.conv1 = nn.Sequential( # input shape (1, 28, 28) nn.Conv2d( in_channels=1, # input height #也就是這一層輸入進去時候數據的神經元數,第一層顯然是1 out_channels=5, # n_filters #輸出神經元數,固然越多越好,這裏寫16 kernel_size=5, # filter size stride=1, # filter movement/step padding=2, # 若是想要 con2d 出來的圖片長寬沒有變化, padding=(kernel_size-1)/2 當 stride=1 ), # output shape (5, 28, 28) nn.ReLU(), # activation nn.MaxPool2d(kernel_size=2), # 在 2x2 空間裏向下採樣, output shape (5, 14, 14) ) self.conv2 = nn.Sequential( # input shape (5, 14, 14) nn.Conv2d(5, 32, 5, 1, 2), # output shape (32, 14, 14) #把5繼續深化到32 nn.ReLU(), # activation nn.MaxPool2d(2), # output shape (32, 7, 7) ) self.out = nn.Linear(32 * 7 * 7, 10) # fully connected layer, output 10 classes def forward(self, x): x = self.conv1(x) x = self.conv2(x) x = x.view(x.size(0), -1) # 展平多維的卷積圖成 (batch_size, 32 * 7 * 7) view就是reshape output = self.out(x) return output cnn = CNN() print(cnn) # net architecture optimizer = torch.optim.Adam(cnn.parameters(), lr=LR) # optimize all cnn parameters loss_func = nn.CrossEntropyLoss() # the target label is not one-hotted # training and testing for epoch in range(EPOCH): for step, (b_x, b_y) in enumerate(train_loader): # 分配 batch data, normalize x when iterate train_loader output = cnn(b_x) # cnn output loss = loss_func(output, b_y) # cross entropy loss optimizer.zero_grad() # clear gradients for this training step loss.backward() # backpropagation, compute gradients optimizer.step() # apply gradients test_output = cnn(test_x[:10]) #test_output:10*10 print(test_output) print(torch.max(test_output, 1)) #torch.max參數裏面寫1就是返回最大值所在的索引值. pred_y = torch.max(test_output, 1)[1].data.numpy().squeeze() print(pred_y, 'prediction number') print(test_y[:10].numpy(), 'real number')
lstm跑mnist
''' Rnn與LSTM rnn:是循環記憶.也就是學習第n句話是根據前面n-1句和這個第n句一塊兒來決定這句話是什麼意思. 可是梯度爆炸或者梯度消失會使得rnn無法學習過久遠的記憶.而有一些意思就是被久遠的東西所決定. 好比:英語喜歡把主謂賓放前面,修飾詞都放後面.就很難學到關鍵信息 LSTM:長短時記憶.能夠把前面記憶的東西加一個權重,越重要的東西權重越大,就是長時間記憶. 設置對於重要記憶,梯度直接提取,不用bp反覆的迭代,這樣久遠的重要東西仍然效果強力.(感受本身寫會很複雜) ''' #LSTM跑mnist import torch from torch import nn import torchvision import torchvision.datasets as dsets import torchvision.transforms as transforms import matplotlib.pyplot as plt import torch import torch.nn as nn import torch.utils.data as Data import torchvision # 數據庫模塊 import matplotlib.pyplot as plt torch.manual_seed(1) # reproducible # Hyper Parameters EPOCH = 1 # 訓練整批數據多少次, 爲了節約時間, 咱們只訓練一次 BATCH_SIZE = 64 TIME_STEP = 28 # rnn 時間步數 / 圖片高度 INPUT_SIZE = 28 # rnn 每步輸入值 / 圖片每行像素 LR = 0.01 # learning rate DOWNLOAD_MNIST = True # 若是你已經下載好了mnist數據就寫上 Fasle # Mnist 手寫數字 train_data = torchvision.datasets.MNIST( root='./mnist/', # 保存或者提取位置 train=True, # this is training data transform=torchvision.transforms.ToTensor(), # 轉換 PIL.Image or numpy.ndarray 成 # torch.FloatTensor (C x H x W), 訓練的時候 normalize 成 [0.0, 1.0] 區間 download=DOWNLOAD_MNIST, # 沒下載就下載, 下載了就不用再下了 ) test_data = torchvision.datasets.MNIST(root='./mnist/', train=False) # 批訓練 50samples, 1 channel, 28x28 (50, 1, 28, 28) train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True) # 爲了節約時間, 咱們測試時只測試前2000個 test_x = torch.unsqueeze(test_data.test_data, dim=1).type(torch.FloatTensor)[:2000]/255. # shape from (2000, 28, 28) to (2000, 1, 28, 28), value in range(0,1) test_y = test_data.test_labels[:2000] class RNN(nn.Module): def __init__(self): super(RNN, self).__init__() #rnn理解圖片是把圖片看做一個28行的文件.一行有28個字符,也就是input_size=28, self.rnn = nn.LSTM( # LSTM 效果要比 nn.RNN() 好多了 input_size=28, # 圖片每行的數據像素點 hidden_size=64, # rnn hidden unit num_layers=1, # 有幾層 RNN layers batch_first=True, # input & output 會是以 batch size 爲第一維度的特徵集 e.g. (batch, time_step, input_size) ) self.out = nn.Linear(64, 10) # 輸出層 def forward(self, x): # x shape (batch, time_step, input_size) # r_out shape (batch, time_step, output_size) # h_n shape (n_layers, batch, hidden_size) LSTM 有兩個 hidden states, h_n 是分線, h_c 是主線 # h_c shape (n_layers, batch, hidden_size) r_out, (h_n, h_c) = self.rnn(x, None) # None 表示 hidden state 會用全0的 state # 選取最後一個時間點的 r_out 輸出,也就是圖片的最後一行,由於他使用了全部圖片信息,用他來 #輸出最有表明性,確定效果最好 # 這裏 r_out[:, -1, :] 的值也是 h_n 的值 #r_out:64*28*64 out = self.out(r_out[:, -1, :]) return out rnn = RNN() print(rnn) optimizer = torch.optim.Adam(rnn.parameters(), lr=LR) # optimize all parameters loss_func = nn.CrossEntropyLoss() # the target label is not one-hotted # training and testing for epoch in range(EPOCH): for step, (x, b_y) in enumerate(train_loader): # gives batch data b_x = x.view(-1, 28, 28) # reshape x to (batch, time_step, input_size) output = rnn(b_x) # rnn output loss = loss_func(output, b_y) # cross entropy loss optimizer.zero_grad() # clear gradients for this training step loss.backward() # backpropagation, compute gradients optimizer.step() # apply gradients test_output = rnn(test_x[:10].view(-1, 28, 28)) pred_y = torch.max(test_output, 1)[1].data.numpy().squeeze() print(pred_y, 'prediction number') print(test_y[:10], 'real number')
rnn迴歸
import torch from torch import nn import numpy as np import matplotlib.pyplot as plt torch.manual_seed(1) # reproducible # Hyper Parameters TIME_STEP = 10 # rnn time step / image height INPUT_SIZE = 1 # rnn input size / image width LR = 0.02 # learning rate DOWNLOAD_MNIST = False # set to True if haven't download the data class RNN(nn.Module): def __init__(self): super(RNN, self).__init__() self.rnn = nn.RNN( # 這回一個普通的 RNN 就能勝任 input_size=1, hidden_size=32, # rnn hidden unit num_layers=1, # 有幾層 RNN layers batch_first=True, # input & output 會是以 batch size 爲第一維度的特徵集 e.g. (batch, time_step, input_size) ) self.out = nn.Linear(32, 1) def forward(self, x, h_state): # 由於 hidden state 是連續的, 因此咱們要一直傳遞這一個 state # x (batch, time_step, input_size) # h_state (n_layers, batch, hidden_size) # r_out (batch, time_step, output_size) r_out, h_state = self.rnn(x, h_state) # h_state 也要做爲 RNN 的一個輸入 outs = [] # 保存全部時間點的預測值 for time_step in range(r_out.size(1)): # 對每個時間點計算 output outs.append(self.out(r_out[:, time_step, :])) return torch.stack(outs, dim=1), h_state rnn = RNN() print(rnn) optimizer = torch.optim.Adam(rnn.parameters(), lr=LR) # optimize all rnn parameters loss_func = nn.MSELoss() h_state = None # 要使用初始 hidden state, 能夠設成 None for step in range(100): start, end = step * np.pi, (step+1)*np.pi # time steps # sin 預測 cos steps = np.linspace(start, end, 10, dtype=np.float32) x_np = np.sin(steps) # float32 for converting torch FloatTensor y_np = np.cos(steps) x = torch.from_numpy(x_np[np.newaxis, :, np.newaxis]) # shape (batch, time_step, input_size) y = torch.from_numpy(y_np[np.newaxis, :, np.newaxis]) prediction, h_state = rnn(x, h_state) # rnn 對於每一個 step 的 prediction, 還有最後一個 step 的 h_state # !! 下一步十分重要 !! h_state = h_state.data # 要把 h_state 從新包裝一下才能放入下一個 iteration, 否則會報錯 loss = loss_func(prediction, y) # cross entropy loss optimizer.zero_grad() # clear gradients for this training step loss.backward() # backpropagation, compute gradients optimizer.step() # apply gradients if step%5==0: print('loss:',loss)
自編碼
import torch import torch.nn as nn import torch.utils.data as Data import torchvision import matplotlib.pyplot as plt # 超參數 EPOCH = 1 BATCH_SIZE = 64 LR = 0.005 DOWNLOAD_MNIST = True # 下過數據的話, 就能夠設置成 False N_TEST_IMG = 5 # 到時候顯示 5張圖片看效果, 如上圖一 # Mnist digits dataset train_data = torchvision.datasets.MNIST( root='./mnist/', train=True, # this is training data transform=torchvision.transforms.ToTensor(), # Converts a PIL.Image or numpy.ndarray to # torch.FloatTensor of shape (C x H x W) and normalize in the range [0.0, 1.0] download=DOWNLOAD_MNIST, # download it if you don't have it ) class AutoEncoder(nn.Module): def __init__(self): super(AutoEncoder, self).__init__() # 壓縮 self.encoder = nn.Sequential( nn.Linear(28*28, 128), nn.Tanh(), nn.Linear(128, 64), nn.Tanh(), nn.Linear(64, 12), nn.Tanh(), nn.Linear(12, 3), # 壓縮成3個特徵, 進行 3D 圖像可視化 ) # 解壓 self.decoder = nn.Sequential( nn.Linear(3, 12), nn.Tanh(), nn.Linear(12, 64), nn.Tanh(), nn.Linear(64, 128), nn.Tanh(), nn.Linear(128, 28*28), nn.Sigmoid(), # 激勵函數讓輸出值在 (0, 1) ) def forward(self, x): encoded = self.encoder(x) decoded = self.decoder(encoded) return encoded, decoded autoencoder = AutoEncoder() optimizer = torch.optim.Adam(autoencoder.parameters(), lr=LR) loss_func = nn.MSELoss() train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True) for epoch in range(EPOCH): for step, (x, b_label) in enumerate(train_loader): b_x = x.view(-1, 28*28) # batch x, shape (batch, 28*28) b_y = x.view(-1, 28*28) # batch y, shape (batch, 28*28) encoded, decoded = autoencoder(b_x) loss = loss_func(decoded, b_y) # mean square error optimizer.zero_grad() # clear gradients for this training step loss.backward() # backpropagation, compute gradients optimizer.step() # apply gradients # 要觀看的數據 view_data = train_data.train_data[:200].view(-1, 28*28).type(torch.FloatTensor)/255. encoded_data, _ = autoencoder(view_data) # 提取壓縮的特徵值 fig = plt.figure(2) from mpl_toolkits.mplot3d import Axes3D ax = Axes3D(fig) # 3D 圖 # x, y, z 的數據值 X = encoded_data.data[:, 0].numpy() Y = encoded_data.data[:, 1].numpy() Z = encoded_data.data[:, 2].numpy() values = train_data.train_labels[:200].numpy() # 標籤值 for x, y, z, s in zip(X, Y, Z, values): c = cm.rainbow(int(255*s/9)) # 上色 ax.text(x, y, z, s, backgroundcolor=c) # 標位子 ax.set_xlim(X.min(), X.max()) ax.set_ylim(Y.min(), Y.max()) ax.set_zlim(Z.min(), Z.max()) plt.show()
lstm 加入 bn,自動調整學習率, 梯度clip.爲了之後修改方便
''' Rnn與LSTM rnn:是循環記憶.也就是學習第n句話是根據前面n-1句和這個第n句一塊兒來決定這句話是什麼意思. 可是梯度爆炸或者梯度消失會使得rnn無法學習過久遠的記憶.而有一些意思就是被久遠的東西所決定. 好比:英語喜歡把主謂賓放前面,修飾詞都放後面.就很難學到關鍵信息 LSTM:長短時記憶.能夠把前面記憶的東西加一個權重,越重要的東西權重越大,就是長時間記憶. 設置對於重要記憶,梯度直接提取,不用bp反覆的迭代,這樣久遠的重要東西仍然效果強力.(感受本身寫會很複雜) ''' #LSTM跑mnist import torch from torch import nn import torchvision import torchvision.datasets as dsets import torchvision.transforms as transforms import matplotlib.pyplot as plt import torch import torch.nn as nn import torch.utils.data as Data import torchvision # 數據庫模塊 import matplotlib.pyplot as plt torch.manual_seed(1) # reproducible # Hyper Parameters EPOCH = 1 # 訓練整批數據多少次, 爲了節約時間, 咱們只訓練一次 BATCH_SIZE =64 TIME_STEP = 28 # rnn 時間步數 / 圖片高度 INPUT_SIZE = 28 # rnn 每步輸入值 / 圖片每行像素 LR = 0.001 # learning rate DOWNLOAD_MNIST = True # 若是你已經下載好了mnist數據就寫上 Fasle # Mnist 手寫數字 train_data = torchvision.datasets.MNIST( root='./mnist/', # 保存或者提取位置 train=True, # this is training data transform=torchvision.transforms.ToTensor(), # 轉換 PIL.Image or numpy.ndarray 成 # torch.FloatTensor (C x H x W), 訓練的時候 normalize 成 [0.0, 1.0] 區間 download=DOWNLOAD_MNIST, # 沒下載就下載, 下載了就不用再下了 ) test_data = torchvision.datasets.MNIST(root='./mnist/', train=False) # 批訓練 50samples, 1 channel, 28x28 (50, 1, 28, 28) train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True) # 爲了節約時間, 咱們測試時只測試前2000個 test_x = torch.unsqueeze(test_data.test_data, dim=1).type(torch.FloatTensor)[:2000]/255. # shape from (2000, 28, 28) to (2000, 1, 28, 28), value in range(0,1) test_y = test_data.test_labels[:2000] class RNN(nn.Module): def __init__(self): super(RNN, self).__init__() #rnn理解圖片是把圖片看做一個28行的文件.一行有28個字符,也就是input_size=28, self.rnn = nn.LSTM( # LSTM 效果要比 nn.RNN() 好多了 input_size=28, # 圖片每行的數據像素點 hidden_size=120, # rnn hidden unit num_layers=1, # 有幾層 RNN layers batch_first=True, # input & output 會是以 batch size 爲第一維度的特徵集 e.g. (batch, time_step, input_size) ) self.out = nn.Linear(120, 10) # 輸出層 self.out2=nn.Linear(28,28) def forward(self, x): # x shape (batch, time_step, input_size) # r_out shape (batch, time_step, output_size) # h_n shape (n_layers, batch, hidden_size) LSTM 有兩個 hidden states, h_n 是分線, h_c 是主線 # h_c shape (n_layers, batch, hidden_size) #bn層,自帶的方法bath_normalization沒看懂,本身手寫一個吧 m = torch.mean(x, dim=0)#計算均值 注意是在batch_size這個dim上作mean. std = torch.std(x, dim=0)#計算標準差 epsilon=0.001 #必須寫的足夠小才能歸一化,我寫0.01都不行,這個須要測試. x_normed = (x - m) / (std + epsilon)#歸一化 x=x_normed x=self.out2(x)#這行是爲了把bn的變化經過放射再擬合回去,保證數據的先後一致 r_out, (h_n, h_c) = self.rnn(x, None) # None 表示 hidden state 會用全0的 state # 選取最後一個時間點的 r_out 輸出,也就是圖片的最後一行,由於他使用了全部圖片信息,用他來 #輸出最有表明性,確定效果最好 # 這裏 r_out[:, -1, :] 的值也是 h_n 的值 #r_out:64*28*64 out = self.out(r_out[:, -1, :]) #out:64*28*10 return out rnn = RNN() print(rnn) #https://www.cnblogs.com/bamtercelboo/p/7469005.html這篇調參方法設置的.加入L2懲罰項 optimizer = torch.optim.Adam(rnn.parameters(), lr=LR, weight_decay=1e-8) # optimize all parameters loss_func = nn.CrossEntropyLoss() # the target label is not one-hotted # training and testing def adjust_learning_rate(optimizer, decay_rate=.9): for param_group in optimizer.param_groups: param_group['lr'] = param_group['lr'] * decay_rate for epoch in range(EPOCH): for step, (x, b_y) in enumerate(train_loader): # gives batch data #下面2行動態學習率,效果不是很明顯 if step%200==0: adjust_learning_rate(optimizer) b_x = x.view(-1, 28, 28) # reshape x to (batch, time_step, input_size) output = rnn(b_x) # rnn output loss = loss_func(output, b_y) # cross entropy loss optimizer.zero_grad() # clear gradients for this training step loss.backward() # backpropagation, compute gradients #進行梯度切分:爲何沒有設置最小的? torch.nn.utils.clip_grad_norm_(rnn.parameters(), max_norm=1,norm_type=4) optimizer.step() # apply gradients if step%20==0: print(loss) # test_output = rnn(test_x[:10].view(-1, 28, 28)) # pred_y = torch.max(test_output, 1)[1].data.numpy().squeeze() # print(pred_y, 'prediction number') # print(test_y[:10], 'real number')
keras,lstm作時間序列分析模板:
#庫包的安裝:https://blog.csdn.net/yangqiang200608/article/details/78719568?locationNum=9&fps=1 #keras的文檔:http://keras-cn.readthedocs.io/en/latest/layers/core_layer/#dense #老外的文檔:https://machinelearningmastery.com/time-series-prediction-lstm-recurrent-neural-networks-python-keras/ import numpy import matplotlib.pyplot as plt from pandas import read_csv import numpy #把老外的代碼改爲農行的小時作一下預測 # load the dataset dataframe = read_csv(r'd:\lstm_try.csv', usecols=[1], engine='python', skipfooter=3) dataset = dataframe.values dataset = dataset.astype('float32') from sklearn.preprocessing import MinMaxScaler from sklearn.metrics import mean_squared_error #對數據進行時間擴充的函數 def create_dataset(dataset, look_back=3): dataX, dataY = [], [] for i in range(len(dataset)-look_back): a = dataset[i:(i+look_back), 0] #pd裏面取數據的方式, 0表示取第二個維度裏面index是0的數據 dataX.append(a) #a是前2個歷史數據 dataY.append(dataset[i + look_back, 0]) #Y是當前數據 #X return numpy.array(dataX), numpy.array(dataY) ''' (array([[ 112., 118., 132.], [ 118., 132., 129.], [ 132., 129., 121.], [ 129., 121., 135.], [ 121., 135., 148.], [ 135., 148., 148.], [ 148., 148., 136.], [ 148., 136., 119.], [ 136., 119., 104.], [ 119., 104., 118.], [ 104., 118., 115.], [ 118., 115., 126.], [ 115., 126., 141.], [ 126., 141., 135.], [ 141., 135., 125.], [ 135., 125., 149.], [ 125., 149., 170.], [ 149., 170., 170.], [ 170., 170., 158.], [ 170., 158., 133.], [ 158., 133., 114.], [ 133., 114., 140.], [ 114., 140., 145.], [ 140., 145., 150.], [ 145., 150., 178.], [ 150., 178., 163.], [ 178., 163., 172.], [ 163., 172., 178.], [ 172., 178., 199.], [ 178., 199., 199.], [ 199., 199., 184.], [ 199., 184., 162.], [ 184., 162., 146.], [ 162., 146., 166.], [ 146., 166., 171.], [ 166., 171., 180.], [ 171., 180., 193.], [ 180., 193., 181.], [ 193., 181., 183.], [ 181., 183., 218.], [ 183., 218., 230.], [ 218., 230., 242.], [ 230., 242., 209.], [ 242., 209., 191.], [ 209., 191., 172.], [ 191., 172., 194.], [ 172., 194., 196.], [ 194., 196., 196.], [ 196., 196., 236.], [ 196., 236., 235.], [ 236., 235., 229.], [ 235., 229., 243.], [ 229., 243., 264.], [ 243., 264., 272.], [ 264., 272., 237.], [ 272., 237., 211.], [ 237., 211., 180.], [ 211., 180., 201.], [ 180., 201., 204.], [ 201., 204., 188.], [ 204., 188., 235.], [ 188., 235., 227.], [ 235., 227., 234.], [ 227., 234., 264.], [ 234., 264., 302.], [ 264., 302., 293.], [ 302., 293., 259.], [ 293., 259., 229.], [ 259., 229., 203.], [ 229., 203., 229.], [ 203., 229., 242.], [ 229., 242., 233.], [ 242., 233., 267.], [ 233., 267., 269.], [ 267., 269., 270.], [ 269., 270., 315.], [ 270., 315., 364.], [ 315., 364., 347.], [ 364., 347., 312.], [ 347., 312., 274.], [ 312., 274., 237.], [ 274., 237., 278.], [ 237., 278., 284.], [ 278., 284., 277.], [ 284., 277., 317.], [ 277., 317., 313.], [ 317., 313., 318.], [ 313., 318., 374.], [ 318., 374., 413.], [ 374., 413., 405.], [ 413., 405., 355.], [ 405., 355., 306.], [ 355., 306., 271.], [ 306., 271., 306.], [ 271., 306., 315.], [ 306., 315., 301.], [ 315., 301., 356.], [ 301., 356., 348.], [ 356., 348., 355.], [ 348., 355., 422.], [ 355., 422., 465.], [ 422., 465., 467.], [ 465., 467., 404.], [ 467., 404., 347.], [ 404., 347., 305.], [ 347., 305., 336.], [ 305., 336., 340.], [ 336., 340., 318.], [ 340., 318., 362.], [ 318., 362., 348.], [ 362., 348., 363.], [ 348., 363., 435.], [ 363., 435., 491.], [ 435., 491., 505.], [ 491., 505., 404.], [ 505., 404., 359.], [ 404., 359., 310.], [ 359., 310., 337.], [ 310., 337., 360.], [ 337., 360., 342.], [ 360., 342., 406.], [ 342., 406., 396.], [ 406., 396., 420.], [ 396., 420., 472.], [ 420., 472., 548.], [ 472., 548., 559.], [ 548., 559., 463.], [ 559., 463., 407.], [ 463., 407., 362.], [ 407., 362., 405.], [ 362., 405., 417.], [ 405., 417., 391.], [ 417., 391., 419.], [ 391., 419., 461.], [ 419., 461., 472.], [ 461., 472., 535.], [ 472., 535., 622.], [ 535., 622., 606.], [ 622., 606., 508.], [ 606., 508., 461.], [ 508., 461., 390.]], dtype=float32), array([ 129., 121., 135., 148., 148., 136., 119., 104., 118., 115., 126., 141., 135., 125., 149., 170., 170., 158., 133., 114., 140., 145., 150., 178., 163., 172., 178., 199., 199., 184., 162., 146., 166., 171., 180., 193., 181., 183., 218., 230., 242., 209., 191., 172., 194., 196., 196., 236., 235., 229., 243., 264., 272., 237., 211., 180., 201., 204., 188., 235., 227., 234., 264., 302., 293., 259., 229., 203., 229., 242., 233., 267., 269., 270., 315., 364., 347., 312., 274., 237., 278., 284., 277., 317., 313., 318., 374., 413., 405., 355., 306., 271., 306., 315., 301., 356., 348., 355., 422., 465., 467., 404., 347., 305., 336., 340., 318., 362., 348., 363., 435., 491., 505., 404., 359., 310., 337., 360., 342., 406., 396., 420., 472., 548., 559., 463., 407., 362., 405., 417., 391., 419., 461., 472., 535., 622., 606., 508., 461., 390., 432.], dtype=float32)) ''' #作數據切分和處理 # fix random seed for reproducibility numpy.random.seed(7) #第一步須要標準化數據,讓訓練更快 # normalize the dataset #http://sklearn.apachecn.org/cn/0.19.0/modules/preprocessing.html#preprocessing-normalization scaler = MinMaxScaler(feature_range=(0, 1)) dataset = scaler.fit_transform(dataset) # split into train and test sets #train_size = int(len(dataset) * 0.95) #test_size = len(dataset) - train_size #train, test = dataset[0:train_size,:], dataset[train_size:len(dataset),:] #look_back = 200 #trainX, trainY = create_dataset(train, look_back) #testX, testY = create_dataset(test, look_back) #我認爲應該先用create_dataset切,而後再用數組切片切成train,test 纔對.改爲了下面的 look_back = 200 a,b=create_dataset(dataset,look_back) train_size = int(len(a) * 0.95) test_size = len(a) - train_size trainX=a[:train_size,:] trainY=b[:train_size] testX=a[train_size:,:] testY=b[train_size:] #下面把中間加一個維度,表示time_step.每個時間片斷是多長.這裏設置1,trainX.shape[1]=look_back trainX = numpy.reshape(trainX, (trainX.shape[0], 1, trainX.shape[1])) testX = numpy.reshape(testX, (testX.shape[0], 1, testX.shape[1])) import numpy import matplotlib.pyplot as plt from pandas import read_csv import math from keras.models import Sequential from keras.layers import Dense from keras.layers import LSTM from sklearn.preprocessing import MinMaxScaler from sklearn.metrics import mean_squared_error #下面是網絡結構,和把數據fit給網絡進行訓練 # create and fit the LSTM network,keras寫深度網絡代碼也太少了. model = Sequential() #不寫activation 默認就是tanh model.add(LSTM(50, input_shape=(1, look_back),dropout=0.5, recurrent_dropout=0.5)) #4表示輸出的維度 #input_dim:輸入維度,當使用該層爲模型首層時,應指定該值(或等價的指定input_shape) model.add(Dense(50, activation='tanh')) model.add(Dense(1, activation='tanh')) model.compile(loss='mean_squared_error', optimizer='adam') model.fit(trainX, trainY, epochs=100, batch_size=1, verbose=0) ''' verbose:日誌顯示,0爲不在標準輸出流輸出日誌信息,1爲輸出進度條記錄,2爲每一個epoch輸出一行記錄 ''' # make predictions trainPredict = model.predict(trainX) testPredict = model.predict(testX) # invert predictions trainPredict = scaler.inverse_transform(trainPredict) trainY = scaler.inverse_transform([trainY]) testPredict = scaler.inverse_transform(testPredict) testY = scaler.inverse_transform([testY]) trainScore = math.sqrt(mean_squared_error(trainY[0], trainPredict[:,0])) print('Train Score: %.2f RMSE' % (trainScore)) wucha=abs(testY[0]-testPredict[:,0])/testY[0] print(type(wucha)) print('絕對值偏差百分比平均:'+str(wucha.sum()/len(wucha))) testScore = math.sqrt(mean_squared_error(testY[0], testPredict[:,0])) print('Test Score: %.2f RMSE' % (testScore))
# -*- coding: utf-8 -*- """ Created on Fri Jul 20 10:58:02 2018 @author: 張博 """ #讀取csv最穩的方法: #f = open(r'C:\Users\張博\Desktop\展現\old.csv') #data = read_csv(f,header=None) ''' 畫圖模板: from matplotlib import pyplot data=[] pyplot.plot(data,color='black') pyplot.show() ''' ''' 獲取當前時間: import datetime nowTime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')#如今 nowTime=((nowTime)[:-3]) print(nowTime) ''' ''' 寫文件的模板 with open(r'c:/234/wucha.txt','w') as f: wucha=str(wucha) f.write(wucha) ''' ''' 手動加斷電的方法:raise ''' # -*- coding: utf-8 -*- """ Created on Fri Jul 20 10:58:02 2018 @author: 張博 """ # -*- coding: utf-8 -*- """ Created on Tue Jul 17 10:54:38 2018 @author: 張博 """ # -*- coding: utf-8 -*- """ Created on Mon Jul 16 17:18:57 2018 @author: 張博 """ # -*- coding: utf-8 -*- """ Spyder Editor This is a temporary script file. """ #2018-07-23,22點54對學習率參數進行for循環來學習哪一個最好RATE for i in range((1)): import os os.environ['CUDA_VISIBLE_DEVICES'] = '0' #使用 GPU 0 import tensorflow as tf from keras.backend.tensorflow_backend import set_session config = tf.ConfigProto() config.gpu_options.allocator_type = 'BFC' #A "Best-fit with coalescing" algorithm, simplified from a version of dlmalloc. config.gpu_options.per_process_gpu_memory_fraction = 1. config.gpu_options.allow_growth = True set_session(tf.Session(config=config)) #老外的教程:很是詳細,最後的多變量,多step模型應該是最終實際應用最好的模型了.也就是這個.py文件寫的內容 #https://machinelearningmastery.com/multivariate-time-series-forecasting-lstms-keras/ ''' SUPER_PARAMETER:通常代碼習慣把超參數寫最開始位置,方便修改和查找 ''' EPOCH=100 LOOK_BACK=24 n_features = 3 #這個問題裏面這個參數不用動,由於只有2個變量 RATE=0.55 shenjing=62 n_hours = LOOK_BACK import pandas as pd from pandas import read_csv from datetime import datetime # load data def parse(x): return datetime.strptime(x, '%Y %m %d %H') data = read_csv(r'E:\output_nonghang\out2.csv') #應該把DD給刪了,天數沒用 #切片和concat便可 tmp1=data.iloc[:,2:3] tmp2=data.iloc[:,3] tmp3=data.iloc[:,1] data.to_csv('c:/234/out00000.csv') # for i in range(len(tmp3)): # if tmp3[i] in range(12,13): # tmp3[i]=1 # if tmp3[i] in range(13,14): # tmp3[i]=2 # else: # tmp3[i]=0 #加一個預處理判斷.判斷數據奇異的點. #方法是:遍歷一遍整個數據,若是這個點的數據比同時工做日或者週末的狀況的mean的0.2還低 #就說明這個點錯了.用上面同比狀況mean來替代. for i in range(len(data)): hour=data.iloc[i]['HH'] week=data.iloc[i]['week'] tmp56=data.query('HH == '+str(hour) +' and '+ 'week=='+str(week)) tmp_sum=tmp56['Sum'].mean() if data.iloc[i]['Sum']< tmp_sum *0.4: data.iloc[i]['Sum']=tmp_sum print('修改了以下行,由於他是異常點') print(i) #修改完畢 tmp1=data.iloc[:,2:3] tmp2=data.iloc[:,3] tmp3=data.iloc[:,1] data=pd.concat([tmp2,tmp3,tmp1],axis=1) print(data) data.to_csv('c:/234/out00000.csv') #由於下面的模板是把預測值放在了第一列.因此對data先作一個變換. #data.to_csv('pollution.csv') from pandas import read_csv from matplotlib import pyplot # load dataset dataset = data values = dataset.values ## specify columns to plot #groups = [0, 1, 2, 3, 5, 6, 7] #i = 1 from pandas import read_csv from matplotlib import pyplot # load dataset #dataset = read_csv('pollution.csv', header=0, index_col=0) ##print(dataset.head()) #values = dataset.values # specify columns to plot #groups = [0, 1, 2, 3, 5, 6, 7] #i = 1 # plot each column #pyplot.figure() #圖中每一行是一個列數據的展示.因此一共有7個小圖,對應7個列指標的變化. #for group in groups: # pyplot.subplot(len(groups), 1, i) # pyplot.plot(values[:, group]) # pyplot.title(dataset.columns[group], y=0.5, loc='right') # i += 1 ##pyplot.show() from math import sqrt from numpy import concatenate from matplotlib import pyplot from pandas import read_csv from pandas import DataFrame from pandas import concat from sklearn.preprocessing import MinMaxScaler from sklearn.preprocessing import LabelEncoder from sklearn.metrics import mean_squared_error from keras.models import Sequential from keras.layers import Dense from keras.layers import LSTM # load dataset # integer encode direction #把標籤標準化而已.好比把1,23,5,7,7標準化以後就變成了0,1,2,3,3 #print('values') #print(values[:5]) #encoder = LabelEncoder() #values[:,4] = encoder.fit_transform(values[:,4]) ## ensure all data is float #values = values.astype('float32') #print('values_after_endoding') #numpy 轉pd import pandas as pd #pd.DataFrame(values).to_csv('values_after_endoding.csv') #從結果能夠看出來encoder函數把這種catogorical的數據轉化成了數值類型, #方便作迴歸. #print(values[:5]) # normalize features,先正規化. #這裏面係數多嘗試(0,1) (-1,1) 或者用其餘正則化方法. scaler = MinMaxScaler(feature_range=(-1, 1)) scaled = scaler.fit_transform(values) print('正規化以後的數據') pd.DataFrame(scaled).to_csv('values_after_normalization.csv') # frame as supervised learning # convert series to supervised learning #n_in:以前的時間點讀入多少,n_out:以後的時間點讀入多少. #對於多變量,都是同時讀入多少.爲了方便,統一按嘴大的來. #print('測試shift函數') # #df = DataFrame(scaled) #print(df) # 從測試看出來shift就是數據同時向下平移,或者向上平移. #print(df.shift(2)) def series_to_supervised(data, n_in=1, n_out=1, dropnan=True): n_vars = 1 if type(data) is list else data.shape[1] df = DataFrame(data) cols, names = [],[] # input sequence (t-n, ... t-1) for i in range(n_in, 0, -1): cols.append(df.shift(i)) names += [('var%d(時間:t-%s)' % (j+1, i)) for j in range(n_vars)] # forecast sequence (t, t+1, ... t+n) for i in range(0, n_out): cols.append(df.shift(-i)) if i == 0: names += [('var%d(時間:t)' % (j+1)) for j in range(n_vars)] else: names += [('var%d(時間:t+%d)' % (j+1, i)) for j in range(n_vars)] # put it all together agg = concat(cols, axis=1) agg.columns = names # drop rows with NaN values if dropnan: agg.dropna(inplace=True) return agg #series_to_supervised函數把多變量時間序列的列拍好. reframed = series_to_supervised(scaled, LOOK_BACK, 1) # drop columns we don't want to predict #咱們只須要預測var1(t)因此把後面的拍都扔了. # split into train and test sets values = reframed.values n_train_hours = int(len(scaled)*0.75) train = values[:n_train_hours, :] test = values[n_train_hours:, :] # split into input and outputs n_obs = n_hours * n_features train_X, train_y = train[:, :n_obs], train[:, -n_features] test_X, test_y = test[:, :n_obs], test[:, -n_features] #print(train_X.shape, len(train_X), train_y.shape) #print(test_X.shape, len(test_X), test_y.shape) #print(train_X) #print(9999999999999999) #print(test_X) #這裏依然是用timesteps=1 #從這個reshape能夠看出來,以前的單變量的feature長度=look_back # 如今的多變量feature長度=look_back*len(variables).就這一個區別. # reshape input to be 3D [samples, timesteps, features] train_X = train_X.reshape((train_X.shape[0], n_hours,n_features)) test_X = test_X.reshape((test_X.shape[0], n_hours, n_features)) #print(train_X.shape, train_y.shape, test_X.shape, test_y.shape) ''' 網絡結構比較小的時候,效率瓶頸在CPU與GPU數據傳輸,這個時候只用cpu會更快。 網絡結構比較龐大的時候,gpu的提速就比較明顯了。 :顯存和內存同樣,屬於隨機存儲,關機後自動清空。 ''' print('開始訓練') # design network model = Sequential() import keras from keras import regularizers from keras import optimizers import keras model.add(keras.layers.recurrent.LSTM(shenjing, input_shape=(train_X.shape[1], train_X.shape[2]),activation='tanh', recurrent_activation='hard_sigmoid', kernel_initializer='random_uniform', bias_initializer='zeros', kernel_regularizer=regularizers.l2(0.01), recurrent_regularizer=regularizers.l2(0.01) , bias_regularizer=regularizers.l2(0.01), dropout=0., recurrent_dropout=0. ,return_sequences=False)) #model.add(Dense(60, activation='tanh',kernel_regularizer=regularizers.l2(0.01), # bias_regularizer=regularizers.l2(0.01))) # returns a sequence of vectors of dimension 32 #model.add(LSTM(32)) # return a single vector of dimension 32 def schedule(epoch): rate=RATE if epoch<3: return 0.002 #開始學的快一點 if epoch<10: return 0.001 if epoch<15: return 0.001*0.5 if epoch<20: return 0.001*rate if epoch<30: return 0.001*rate**2 if epoch<70: return 0.001*rate**3 else: return 0.001*rate**4 #發現這個層是必須加的. # model.add(keras.layers.core.Dropout(0.2, noise_shape=None, seed=None)) learning_rate=keras.callbacks.LearningRateScheduler(schedule) learning_rate2=keras.callbacks.ReduceLROnPlateau(factor=0.5) #input_dim:輸入維度,當使用該層爲模型首層時,應指定該值(或等價的指定input_shape) # model.add(Dense(1000,activation='tanh'),) model.add(Dense(1)) #loss:mse,mae,mape,msle adam = optimizers.Adam(lr=0.001, clipnorm=.5) model.compile(loss='mape', optimizer=adam,metrics=['mae']) # fit network #參數裏面寫validation_data就不用本身手動predict了,能夠直接畫histrory圖像了 history = model.fit(train_X, train_y, epochs=EPOCH, batch_size=1, validation_data=(test_X, test_y), verbose=1, shuffle=False,callbacks=[learning_rate, learning_rate2], ) # plot history #pyplot.plot(history.history['loss'], label='train') #pyplot.plot(history.history['val_loss'], label='test') #pyplot.legend() #pyplot.show() #訓練好後直接作預測便可. # make a prediction yhat = model.predict(test_X) #yhat 這個變量表示y上面加一票的數學符號 #在統計學裏面用來表示算法做用到test上獲得的預測值 test_X = test_X.reshape((test_X.shape[0], n_hours*n_features)) # invert scaling for forecast #由於以前的scale是對初始數據作scale的,inverse回去還須要把矩陣的型拼回去. inv_yhat = concatenate((yhat, test_X[:, -(n_features-1):]), axis=1) inv_yhat = scaler.inverse_transform(inv_yhat) inv_yhat = inv_yhat[:,0]#inverse完再把數據扣出來.多變量這個地方須要的操做要多點 # invert scaling for actual test_y = test_y.reshape((len(test_y), 1)) inv_y = concatenate((test_y, test_X[:, -(n_features-1):]), axis=1) inv_y = scaler.inverse_transform(inv_y) inv_y = inv_y[:,0] with open(r'c:/234/inv_y.txt','w') as f: inv_y1=str(inv_y) f.write(inv_y1) with open(r'c:/234/inv_yhat.txt','w') as f: inv_yhat1=str(inv_yhat) f.write(inv_yhat1) # calculate RMSE rmse = sqrt(mean_squared_error(inv_y, inv_yhat)) # print('RATE:') # print(RATE) print('輸出abs差百分比指標:') #這個污染指數還有0的.干擾很是大 #print(inv_y.shape) #print(inv_yhat.shape) wucha=abs(inv_y-inv_yhat)/(inv_y) #print(wucha) ''' 下面把獲得的abs百分比偏差寫到 文件裏面 ''' #with open(r'c:/234/wucha.txt','w') as f: # print(type(wucha)) # wucha2=list(wucha) # wucha2=str(wucha2) # f.write(wucha2) with open(r'c:/234/sumary.txt','a') as f: rate=str(RATE) f.write(rate+',') shenjing=str(shenjing) f.write(shenjing) f.write(',') wucha2=wucha.mean() wucha2=str(wucha2) f.write(wucha2) f.write('.') f.write('\n') wucha=wucha.mean() print(wucha) inv_y=inv_y inv_yhat=inv_yhat #print('Test RMSE: %.3f' % rmse) import numpy as np from matplotlib import pyplot pyplot.rcParams['figure.figsize'] = (20, 3) # 設置figure_size尺寸 pyplot.rcParams['image.cmap'] = 'gray' # pyplot.plot(inv_y,color='black',linewidth = 0.7) pyplot.plot(inv_yhat ,color='red',linewidth = 0.7) pyplot.show() ''' 獲取當前時間: import datetime nowTime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')#如今 nowTime=((nowTime)[:-3]) print(nowTime) ''' ''' 寫文件的模板 with open(r'c:/234/wucha.txt','w') as f: wucha=str(wucha) f.write(wucha) ''' ''' 手動加斷電的方法:raise NameError #這種加斷點方法靠譜 ''' ''' 畫圖模板: import numpy as np from matplotlib import pyplot pyplot.rcParams['figure.figsize'] = (20, 3) # 設置figure_size尺寸 pyplot.rcParams['image.cmap'] = 'gray' # pyplot.plot(inv_y,color='black',linewidth = 0.7) pyplot.show() ''' #讀取csv最穩的方法: #f = open(r'C:\Users\張博\Desktop\展現\old.csv') #data = read_csv(f,header=None)
實驗樓的java計算器腳本:不是太懂
package ffffff; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.Vector; import java.math.BigDecimal; public class Calculator { // 操做數1,爲了程序的安全,初值必定設置,這裏咱們設置爲0。 String str1 = "0"; // 操做數2 String str2 = "0"; // 運算符 String signal = "+"; // 運算結果 String result = ""; // 如下k1至k2爲狀態開關 // 開關1用於選擇輸入方向,將要寫入str1或str2 int k1 = 1; // 開關2用於記錄符號鍵的次數,若是 k2>1 說明進行的是 2+3-9+8 這樣的多符號運算 int k2 = 1; // 開關3用於標識 str1 是否能夠被清0 ,等於1時能夠,不等於1時不能被清0 int k3 = 1; // 開關4用於標識 str2 是否能夠被清0 int k4 = 1; // 開關5用於控制小數點能否被錄入,等於1時能夠,不爲1時,輸入的小數點被丟掉 int k5 = 1; // store的做用相似於寄存器,用於記錄是否連續按下符號鍵 JButton store; @SuppressWarnings("rawtypes") Vector vt = new Vector(20, 10); // 聲明各個UI組件對象並初始化 JFrame frame = new JFrame("Calculator"); JTextField result_TextField = new JTextField(result, 20); JButton clear_Button = new JButton("Clear"); JButton button0 = new JButton("0"); JButton button1 = new JButton("1"); JButton button2 = new JButton("2"); JButton button3 = new JButton("3"); JButton button4 = new JButton("4"); JButton button5 = new JButton("5"); JButton button6 = new JButton("6"); JButton button7 = new JButton("7"); JButton button8 = new JButton("8"); JButton button9 = new JButton("9"); JButton button_Dian = new JButton("."); JButton button_jia = new JButton("+"); JButton button_jian = new JButton("-"); JButton button_cheng = new JButton("*"); JButton button_chu = new JButton("/"); JButton button_dy = new JButton("="); // 計算機類的構造器 public Calculator() { // 爲按鈕設置等效鍵,便可以經過對應的鍵盤按鍵來代替點擊它 button0.setMnemonic(KeyEvent.VK_0); // 其它等效鍵省略,你能夠自行補充完整 // 設置文本框爲右對齊,使輸入和結果都靠右顯示 result_TextField.setHorizontalAlignment(JTextField.RIGHT); // 將UI組件添加進容器內 JPanel pan = new JPanel(); pan.setLayout(new GridLayout(4, 4, 5, 5)); pan.add(button7); pan.add(button8); pan.add(button9); pan.add(button_chu); pan.add(button4); pan.add(button5); pan.add(button6); pan.add(button_cheng); pan.add(button1); pan.add(button2); pan.add(button3); pan.add(button_jian); pan.add(button0); pan.add(button_Dian); pan.add(button_dy); pan.add(button_jia); pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); JPanel pan2 = new JPanel(); pan2.setLayout(new BorderLayout()); pan2.add(result_TextField, BorderLayout.WEST); pan2.add(clear_Button, BorderLayout.EAST); // 設置主窗口出如今屏幕上的位置 frame.setLocation(300, 200); // 設置窗體不能調大小 frame.setResizable(false); frame.getContentPane().setLayout(new BorderLayout()); frame.getContentPane().add(pan2, BorderLayout.NORTH); frame.getContentPane().add(pan, BorderLayout.CENTER); frame.pack(); frame.setVisible(true); // 事件處理程序 // 數字鍵 class Listener implements ActionListener { @SuppressWarnings("unchecked") public void actionPerformed(ActionEvent e) { String ss = ((JButton) e.getSource()).getText(); store = (JButton) e.getSource(); vt.add(store); if (k1 == 1) { if (k3 == 1) { str1 = ""; // 還原開關k5狀態 k5 = 1; } str1 = str1 + ss; k3 = k3 + 1; // 顯示結果 result_TextField.setText(str1); } else if (k1 == 2) { if (k4 == 1) { str2 = ""; // 還原開關k5狀態 k5 = 1; } str2 = str2 + ss; k4 = k4 + 1; result_TextField.setText(str2); } } } // 輸入的運算符號的處理 class Listener_signal implements ActionListener { @SuppressWarnings("unchecked") public void actionPerformed(ActionEvent e) { String ss2 = ((JButton) e.getSource()).getText(); store = (JButton) e.getSource(); vt.add(store); if (k2 == 1) { // 開關 k1 爲 1 時向數 1 寫輸入值,爲2時向數2寫輸入值。 k1 = 2; k5 = 1; signal = ss2; k2 = k2 + 1;// 按符號鍵的次數 } else { int a = vt.size(); JButton c = (JButton) vt.get(a - 2); if (!(c.getText().equals("+")) && !(c.getText().equals("-")) && !(c.getText().equals("*")) && !(c.getText().equals("/"))) { cal(); str1 = result; // 開關 k1 爲 1 時,向數 1 寫值,爲2時向數2寫 k1 = 2; k5 = 1; k4 = 1; signal = ss2; } k2 = k2 + 1; } } } // 清除鍵的邏輯(Clear) class Listener_clear implements ActionListener { @SuppressWarnings("unchecked") public void actionPerformed(ActionEvent e) { store = (JButton) e.getSource(); vt.add(store); k5 = 1; k2 = 1; k1 = 1; k3 = 1; k4 = 1; str1 = "0"; str2 = "0"; signal = ""; result = ""; result_TextField.setText(result); vt.clear(); } } // 等於鍵的邏輯 class Listener_dy implements ActionListener { @SuppressWarnings("unchecked") public void actionPerformed(ActionEvent e) { store = (JButton) e.getSource(); vt.add(store); cal(); // 還原各個開關的狀態 k1 = 1; k2 = 1; k3 = 1; k4 = 1; str1 = result; } } // 小數點的處理 class Listener_xiaos implements ActionListener { @SuppressWarnings("unchecked") public void actionPerformed(ActionEvent e) { store = (JButton) e.getSource(); vt.add(store); if (k5 == 1) { String ss2 = ((JButton) e.getSource()).getText(); if (k1 == 1) { if (k3 == 1) { str1 = ""; // 還原開關k5狀態 k5 = 1; } str1 = str1 + ss2; k3 = k3 + 1; // 顯示結果 result_TextField.setText(str1); } else if (k1 == 2) { if (k4 == 1) { str2 = ""; // 還原開關k5的狀態 k5 = 1; } str2 = str2 + ss2; k4 = k4 + 1; result_TextField.setText(str2); } } k5 = k5 + 1; } } // 註冊各個監聽器,即綁定事件響應邏輯到各個UI組件上 Listener_dy jt_dy = new Listener_dy(); // 監聽數字鍵 Listener jt = new Listener(); // 監聽符號鍵 Listener_signal jt_signal = new Listener_signal(); // 監聽清除鍵 Listener_clear jt_c = new Listener_clear(); // 監聽小數點鍵 Listener_xiaos jt_xs = new Listener_xiaos(); button7.addActionListener(jt); button8.addActionListener(jt); button9.addActionListener(jt); button_chu.addActionListener(jt_signal); button4.addActionListener(jt); button5.addActionListener(jt); button6.addActionListener(jt); button_cheng.addActionListener(jt_signal); button1.addActionListener(jt); button2.addActionListener(jt); button3.addActionListener(jt); button_jian.addActionListener(jt_signal); button0.addActionListener(jt); button_Dian.addActionListener(jt_xs); button_dy.addActionListener(jt_dy); button_jia.addActionListener(jt_signal); clear_Button.addActionListener(jt_c); // 窗體關閉事件的響應程序 frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } // 計算邏輯 public void cal() { // 操做數1 double a2; // 操做數2 double b2; // 運算符 String c = signal; // 運算結果 double result2 = 0; if (c.equals("")) { result_TextField.setText("Please input operator"); } else { // 手動處理小數點的問題 if (str1.equals(".")) str1 = "0.0"; if (str2.equals(".")) str2 = "0.0"; a2 = Double.valueOf(str1).doubleValue(); b2 = Double.valueOf(str2).doubleValue(); if (c.equals("+")) { result2 = a2 + b2; } if (c.equals("-")) { result2 = a2 - b2; } if (c.equals("*")) { BigDecimal m1 = new BigDecimal(Double.toString(a2)); BigDecimal m2 = new BigDecimal(Double.toString(b2)); result2 = m1.multiply(m2).doubleValue(); } if (c.equals("/")) { if (b2 == 0) { result2 = 0; } else { result2 = a2 / b2; } } result = ((new Double(result2)).toString()); result_TextField.setText(result); } } @SuppressWarnings("unused") public static void main(String[] args) { // 設置程序顯示的界面風格,能夠去除 try { UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); } catch (Exception e) { e.printStackTrace(); } Calculator cal = new Calculator(); } }
加強學習的學習:
1. pip install gym
能夠看到,加強學習和監督學習的區別主要有如下兩點:
1. 加強學習是試錯學習(Trail-and-error),因爲沒有直接的指導信息,智能體要以不斷與環境進行交互,經過試錯的方式來得到最佳策略。
2. 延遲迴報,加強學習的指導信息不多,並且每每是在過後(最後一個狀態)纔給出的,這就致使了一個問題,就是得到正回報或者負回報之後,如何將回報分配給前面的狀態。
上篇咱們提到加強學習學到的是一個從環境狀態到動做的映射(即行爲策略),記爲策略π: S→A。而加強學習每每又具備延遲迴報的特色: 若是在第n步輸掉了棋,那麼只有狀態sn和動做an得到了當即回報r(sn,an)=-1,前面的全部狀態當即回報均爲0。因此對於以前的任意狀態s和動做a,當即回報函數r(s,a)沒法說明策略的好壞。於是須要定義值函數(value function,又叫效用函數)來代表當前狀態下策略π的長期影響。
價值函數:第二行有錯誤多寫了一個γ.
當一個策略取定,就是說Si,ai 這個數組取定.那麼擬合下面這個等比函數.
其中ri表示將來第i步回報,
http://blog.jobbole.com/71431/
1.基本方法是矩陣不停的乘法,一直到收斂
2.利用加個機率來更改迭代公式便可解決終止點問題和陷阱問題.
從新學機器學習:
https://blog.csdn.net/supercally/article/details/54754787
https://blog.csdn.net/Young_Gy/article/details/73485518
這裏面的max是對a'來取得.由於s'已經取定了.
●對於bellman公式的理解.
這個Q表是2維的,行表示s取值,列表示a取值.
爲何是這個公式:r表示原來的Q(s,a),max(Q(s',a'))表示s'狀態的最大價值.用這個價值來表示s'狀態的價值.(這麼作是合理的,
由於咱們的決策是每一步按照百分之90的機率選最大的action.因此這個最大價值來替換價值是幾乎必然事件).
因此他也就是Q(s,a)這一步走完會得到的reward.
●代碼和理解:
● 用dnn跑nlp 準確率0.85
# -*- coding: utf-8 -*- """ Created on Fri Jul 20 10:58:02 2018 #若是跑不了就是編碼問題,用記事本另存一下,把編碼改爲utf-8保存便可. #利用cmd跑這種畫圖程序,就能旋轉圖片了.spyder不能旋轉 @author: 張博 """ ''' 讀取csv最穩的方法: f=open(r'C:/Users/old.csv') data = read_csv(f,header=None) ''' ''' 畫圖模板: from matplotlib import pyplot data=[] pyplot.plot(data,color='black') pyplot.show() ''' ''' 獲取當前時間: import datetime nowTime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')#如今 nowTime=((nowTime)[:-3]) print(nowTime) ''' ''' 寫文件的模板 with open(r'c:/234/wucha.txt','w') as f: wucha=str(wucha) f.write(wucha) ''' ''' 手動加斷電的方法:raise ''' ''' excel表格實用技巧: 全選而後選開始-行和列-最適合的列寬. 這樣看錶格清晰多了! ''' ''' 時間序列畫圖 from matplotlib import pyplot #畫布大小 pyplot.rcParams['figure.figsize'] = (300, 3) # 設置figure_size尺寸 import matplotlib.dates as mdates ax=plt.gca() pyplot.rcParams['image.cmap'] = 'gray' # xfmt = mdates.DateFormatter('%y-%m-%d %H:%M') ax.xaxis.set_major_formatter(xfmt) #下面這個是時間序列的間隔時間 plt.xticks(pd.date_range(data[0][0],data[-1][0],freq='2H'),rotation=90) #樣式 pyplot.plot(data[:,0],data[:,1],color='red',linewidth = 0.7) pyplot.show() ''' ''' #畫3d import matplotlib.font_manager as fm import matplotlib.pyplot as plt import numpy as np from mpl_toolkits.mplot3d import Axes3D from matplotlib import pyplot pyplot.rcParams['figure.figsize'] = (3, 3) # 設置figure_size尺寸 fig=plt.figure() ax3d=Axes3D(fig) #繪製3D圖形 ax3d.scatter(data[:,1],data[:,2],data[:,0],c='r',marker=".") pyplot.show() ''' ''' 非數值編碼 #編碼 from sklearn.preprocessing import LabelEncoder a=a.values #切換成ndarry encoder = LabelEncoder() for i in range(5): a[:,i] = encoder.fit_transform(a[:,i]) ''' ''' #標準化 from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler(feature_range=(0, 1)) a = scaler.fit_transform(a) print(a) ''' ''' 降維可視化: tSNE的核心思想是:把高維數據看作高維空間中的點xixi,而後用流形方法將其映射 到低維空間中的yiyi,要求保持其空間距離。即高維空間相距較近/遠的點, 映射到低維空間中仍然較近/遠。爲了讓捱得近的點靠的更近,距離用高斯函數來度量 from sklearn.manifold import TSNE #data能夠是多少維均可以,都能降成2維 tsne=TSNE() tsne.fit_transform(data) #進行數據降維,降成兩維 #a=tsne.fit_transform(data_zs) #a是一個array,a至關於下面的tsne_embedding_ tsne=pd.DataFrame(tsne.embedding_) #轉換數據格式 print(tsne) tsne['聚類類別']=label_pred print(tsne) d=tsne[tsne[u'聚類類別']==0] plt.plot(d[0],d[1],'r.') d=tsne[tsne[u'聚類類別']==1] plt.plot(d[0],d[1],'go') d=tsne[tsne[u'聚類類別']==2] plt.plot(d[0],d[1],'b*') d=tsne[tsne[u'聚類類別']==3] plt.plot(d[0],d[1],'y+') plt.show() ''' ''' 下面咱們用dnn來解決nlp問題 ''' # 探索一下數據狀況 # -*- coding: utf-8 -*- import matplotlib.pyplot as plt import numpy as np from keras.datasets import imdb from keras.layers import Embedding, Flatten, Dense from keras.models import Sequential from keras.preprocessing import sequence #查詢這個文檔https://keras.io/datasets/ #''' #果斷把keras裏面的7大數據集都下載下來學習用: #from keras.datasets 找這個.py文件.spyder裏面右鍵選擇go to definition便可逐步深刻就能找到 #7個下載地址. #下載完進入C:\Users\張博\.keras\datasets 裏面把下載後的放裏面便可. #要問問什麼這麼作,答案就是看源代碼便可.逐步go to definition找代碼裏面語句找到的方法. #''' ## EDA # 加載數據,這個數據來自: https://s3.amazonaws.com/text-datasets/imdb_full.pkl (x_train, y_train), (x_test, y_test) = imdb.load_data() ''' keras官方文檔地址:比中文的全多了 https://keras.io/datasets/ http://keras-cn.readthedocs.io/en/latest/other/datasets/ ''' # 探索一下數據狀況 print(y_train.shape) print(y_train[24000]) print(type(y_train[24000])) ''' 從打印能夠看出來x_train的數據是一個25000*1個數組的數據. 在keras提供的IMDB數據集中,word被映射爲一個大於0的整數,表示該單詞出現頻率的排名, 這樣處理的目的是爲了方便按照詞頻過濾單詞,其中0用於表示unknown word x_train的數據是一個25000*1個int的數據.獲得的是12500個0,12500個1.表示情感的類別 x_test 和y_test跟上面相似. ''' lens = list(map(len, x_train)) #len表示全部數列的長度 print(lens[0]) print(len(x_train[0])) avg_len = np.mean(lens) print(avg_len) print(range(min(lens), max(lens) + 50, 50)) plt.hist(lens, bins=range(min(lens), max(lens) + 50, 50)) plt.show() ''' 獲得hist圖表示長度的分佈狀況 ''' # 因爲長度不一樣,這裏取相同的長度 m = max(max(list(map(len, x_train))), max(list(map(len, x_test)))) print(m) print(x_train.shape) #%% print('m=%d' % m) maxword = min(400, m) print(x_train.shape) x_train = sequence.pad_sequences(x_train, maxlen=maxword) ''' 上一步作完就變成2維tensor了 ''' print(x_train.shape) x_test = sequence.pad_sequences(x_test, maxlen=maxword) print(len(x_train[1546])) ''' 看出來x_train裏面全都是長度400的list ''' print(x_train.shape) print(y_train.shape) print(x_test.shape) print(y_test.shape) #詞數 vocab_siz = np.max([np.max(x_train[i]) for i in range(x_train.shape[0])]) + 1 ''' 最高的詞頻 ''' print(x_train[0]) print('vocab_siz=%d' % vocab_siz) #表示一共有多少個單詞 print('x_train.shape=[%d,%d]' % (x_train.shape[0], x_train.shape[1])) ''' 下面就是feature 400 ,sample 25000的dnn學習便可. ''' #構建模型 model = Sequential() # 第一層是嵌入層,矩陣爲 vocab_siz * 64 ''' maxword=400 ''' ''' 任務:理解embedding層的做用和用法: 官網例子: model = Sequential() model.add(Embedding(1000, 64, input_length=10)) # the model will take as input an integer matrix of size (batch, input_length). # the largest integer (i.e. word index) in the input should be no larger than 999 (vocabulary size). # now model.output_shape == (None, 10, 64), where None is the batch dimension. input_array = np.random.randint(1000, size=(32, 10)) model.compile('rmsprop', 'mse') output_array = model.predict(input_array) assert output_array.shape == (32, 10, 64) ''' #跑一下例子也無妨, ''' 本質上embedding層是一個編碼層從下面例子能夠看出來. 仍是nlp的例子,下面例子中0到999中一個數字表明一個漢字,那麼input_array就表示 32*10個漢字.然而這種用0到999來表示一個漢字顯然不符合漢字的意義.(這個構造是頻率表排序) 例如我用0表示我,1表示是,2表示他.顯然0和1不類似,0和2類似.可是編碼上0,1,2看不出來的. 這就須要一個只有weight的全連接層來自動學習編碼規則.學習如何從0到999每個都編碼 到一個64長度的向量.這樣一個64長度的向量來表示一個漢字,就很是舒服了.處理效率也高了. 比你1000要快多了(由於1000的本質是1000維向量). input_length參數很是重要他表示你輸入數據的列數. 總結:一句話:把以前的one-hot編碼 32*10*1000 壓縮到了32*10*64,速度快了好多!!!!!!!! ps:這個層是npl必須加的,也必須加在第一層上. ''' model = Sequential() model.add(Embedding(1000, 64, input_length=10)) # the model will take as input an integer matrix of size (batch, input_length). # the largest integer (i.e. word index) in the input should be no larger than 999 (vocabulary size). # now model.output_shape == (None, 10, 64), where None is the batch dimension. input_array = np.random.randint(1000, size=(32, 10)) model.compile('rmsprop', 'mse') output_array = model.predict(input_array) assert output_array.shape == (32, 10, 64) print(output_array.shape == (32, 10, 64)) #true #重置一下便可. model = Sequential() model.add(Embedding(vocab_siz, 64, input_length=maxword)) #獲得向量25000*maxword*64,這個地方原文寫錯了,說明他沒理解embed層 model.add(Flatten()) # 加入多層全鏈接 model.add(Dense(2000, activation='relu')) model.add(Dense(500, activation='relu')) model.add(Dense(200, activation='relu')) model.add(Dense(50, activation='relu')) # 最後一層輸進0~1之間的值,像lr那樣 model.add(Dense(1, activation='sigmoid')) # 計算 model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) print(model.summary()) #訓練 model.fit(x_train, y_train, validation_data=(x_test, y_test), batch_size=100, nb_epoch=2, verbose=1) score = model.evaluate(x_test, y_test) print(score)
nlp:
框架ntkl學習:
# -*- coding: utf-8 -*- """ Created on Fri Jul 20 10:58:02 2018 #若是跑不了就是編碼問題,用記事本另存一下,把編碼改爲utf-8保存便可. #利用cmd跑這種畫圖程序,就能旋轉圖片了.spyder不能旋轉 @author: 張博 """ ''' 讀亂碼文件的方法: a=open(u'C:/Users/張博/Desktop/news_sohusite_xml.smarty.dat','r',encoding='utf-8') a=a.readlines() print(a) ''' ''' 讀取csv最穩的方法: f=open(r'C:/Users/old.csv') data = read_csv(f,header=None) ''' ''' 畫圖模板: from matplotlib import pyplot data=[] pyplot.plot(data,color='black') pyplot.show() ''' ''' 獲取當前時間: import datetime nowTime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')#如今 nowTime=((nowTime)[:-3]) print(nowTime) ''' ''' 寫文件的模板 with open(r'c:/234/wucha.txt','w') as f: wucha=str(wucha) f.write(wucha) ''' ''' 手動加斷電的方法:raise ''' ''' excel表格實用技巧: 全選而後選開始-行和列-最適合的列寬. 這樣看錶格清晰多了! ''' ''' 時間序列畫圖 from matplotlib import pyplot #畫布大小 pyplot.rcParams['figure.figsize'] = (300, 3) # 設置figure_size尺寸 import matplotlib.dates as mdates ax=plt.gca() pyplot.rcParams['image.cmap'] = 'gray' # xfmt = mdates.DateFormatter('%y-%m-%d %H:%M') ax.xaxis.set_major_formatter(xfmt) #下面這個是時間序列的間隔時間 plt.xticks(pd.date_range(data[0][0],data[-1][0],freq='2H'),rotation=90) #樣式 pyplot.plot(data[:,0],data[:,1],color='red',linewidth = 0.7) pyplot.show() ''' ''' #畫3d import matplotlib.font_manager as fm import matplotlib.pyplot as plt import numpy as np from mpl_toolkits.mplot3d import Axes3D from matplotlib import pyplot pyplot.rcParams['figure.figsize'] = (3, 3) # 設置figure_size尺寸 fig=plt.figure() ax3d=Axes3D(fig) #繪製3D圖形 ax3d.scatter(data[:,1],data[:,2],data[:,0],c='r',marker=".") pyplot.show() ''' ''' 非數值編碼 #編碼 from sklearn.preprocessing import LabelEncoder a=a.values #切換成ndarry encoder = LabelEncoder() for i in range(5): a[:,i] = encoder.fit_transform(a[:,i]) ''' ''' #標準化 from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler(feature_range=(0, 1)) a = scaler.fit_transform(a) print(a) ''' ''' 降維可視化: tSNE的核心思想是:把高維數據看作高維空間中的點xixi,而後用流形方法將其映射 到低維空間中的yiyi,要求保持其空間距離。即高維空間相距較近/遠的點, 映射到低維空間中仍然較近/遠。爲了讓捱得近的點靠的更近,距離用高斯函數來度量 from sklearn.manifold import TSNE #data能夠是多少維均可以,都能降成2維 tsne=TSNE() tsne.fit_transform(data) #進行數據降維,降成兩維 #a=tsne.fit_transform(data_zs) #a是一個array,a至關於下面的tsne_embedding_ tsne=pd.DataFrame(tsne.embedding_) #轉換數據格式 print(tsne) tsne['聚類類別']=label_pred print(tsne) d=tsne[tsne[u'聚類類別']==0] plt.plot(d[0],d[1],'r.') d=tsne[tsne[u'聚類類別']==1] plt.plot(d[0],d[1],'go') d=tsne[tsne[u'聚類類別']==2] plt.plot(d[0],d[1],'b*') d=tsne[tsne[u'聚類類別']==3] plt.plot(d[0],d[1],'y+') plt.show() ''' ''' 下面咱們用dnn來解決nlp問題 ''' # 探索一下數據狀況 # -*- coding: utf-8 -*- import matplotlib.pyplot as plt import numpy as np from keras.datasets import imdb from keras.layers import Embedding, Flatten, Dense from keras.models import Sequential from keras.preprocessing import sequence #查詢這個文檔https://keras.io/datasets/ #''' #果斷把keras裏面的7大數據集都下載下來學習用: #from keras.datasets 找這個.py文件.spyder裏面右鍵選擇go to definition便可逐步深刻就能找到 #7個下載地址. #下載完進入C:\Users\張博\.keras\datasets 裏面把下載後的放裏面便可. #要問問什麼這麼作,答案就是看源代碼便可.逐步go to definition找代碼裏面語句找到的方法. #''' ## EDA # 加載數據,這個數據來自: https://s3.amazonaws.com/text-datasets/imdb_full.pkl (x_train, y_train), (x_test, y_test) = imdb.load_data() ''' keras官方文檔地址:比中文的全多了 https://keras.io/datasets/ http://keras-cn.readthedocs.io/en/latest/other/datasets/ ''' # 探索一下數據狀況 print(y_train.shape) print(y_train[24000]) print(type(y_train[24000])) ''' 從打印能夠看出來x_train的數據是一個25000*1個數組的數據. 在keras提供的IMDB數據集中,word被映射爲一個大於0的整數,表示該單詞出現頻率的排名, 這樣處理的目的是爲了方便按照詞頻過濾單詞,其中0用於表示unknown word x_train的數據是一個25000*1個int的數據.獲得的是12500個0,12500個1.表示情感的類別 x_test 和y_test跟上面相似. ''' lens = list(map(len, x_train)) #len表示全部數列的長度 print(lens[0]) print(len(x_train[0])) avg_len = np.mean(lens) print(avg_len) print(range(min(lens), max(lens) + 50, 50)) plt.hist(lens, bins=range(min(lens), max(lens) + 50, 50)) plt.show() ''' 獲得hist圖表示長度的分佈狀況 ''' # 因爲長度不一樣,這裏取相同的長度 m = max(max(list(map(len, x_train))), max(list(map(len, x_test)))) print(m) print(x_train.shape) #%% print('m=%d' % m) maxword = min(400, m) print(x_train.shape) x_train = sequence.pad_sequences(x_train, maxlen=maxword) ''' 上一步作完就變成2維tensor了 ''' print(x_train.shape) x_test = sequence.pad_sequences(x_test, maxlen=maxword) print(len(x_train[1546])) ''' 看出來x_train裏面全都是長度400的list ''' print(x_train.shape) print(y_train.shape) print(x_test.shape) print(y_test.shape) #詞數 vocab_siz = np.max([np.max(x_train[i]) for i in range(x_train.shape[0])]) + 1 ''' 最高的詞頻 ''' print(x_train[0]) print('vocab_siz=%d' % vocab_siz) #表示一共有多少個單詞 print('x_train.shape=[%d,%d]' % (x_train.shape[0], x_train.shape[1])) ''' 下面就是feature 400 ,sample 25000的dnn學習便可. ''' #構建模型 model = Sequential() # 第一層是嵌入層,矩陣爲 vocab_siz * 64 ''' maxword=400 ''' ''' 任務:理解embedding層的做用和用法: 官網例子: model = Sequential() model.add(Embedding(1000, 64, input_length=10)) # the model will take as input an integer matrix of size (batch, input_length). # the largest integer (i.e. word index) in the input should be no larger than 999 (vocabulary size). # now model.output_shape == (None, 10, 64), where None is the batch dimension. input_array = np.random.randint(1000, size=(32, 10)) model.compile('rmsprop', 'mse') output_array = model.predict(input_array) assert output_array.shape == (32, 10, 64) ''' #跑一下例子也無妨, ''' 本質上embedding層是一個編碼層從下面例子能夠看出來. 仍是nlp的例子,下面例子中0到999中一個數字表明一個漢字,那麼input_array就表示 32*10個漢字.然而這種用0到999來表示一個漢字顯然不符合漢字的意義.(這個構造是頻率表排序) 例如我用0表示我,1表示是,2表示他.顯然0和1不類似,0和2類似.可是編碼上0,1,2看不出來的. 這就須要一個只有weight的全連接層來自動學習編碼規則.學習如何從0到999每個都編碼 到一個64長度的向量.這樣一個64長度的向量來表示一個漢字,就很是舒服了.處理效率也高了. 比你1000要快多了(由於1000的本質是1000維向量). input_length參數很是重要他表示你輸入數據的列數. 總結:一句話:把以前的one-hot編碼 32*10*1000 壓縮到了32*10*64,速度快了好多!!!!!!!! ps:這個層是npl必須加的,也必須加在第一層上. ''' model = Sequential() model.add(Embedding(1000, 64, input_length=10)) # the model will take as input an integer matrix of size (batch, input_length). # the largest integer (i.e. word index) in the input should be no larger than 999 (vocabulary size). # now model.output_shape == (None, 10, 64), where None is the batch dimension. input_array = np.random.randint(1000, size=(32, 10)) model.compile('rmsprop', 'mse') output_array = model.predict(input_array) assert output_array.shape == (32, 10, 64) print(output_array.shape == (32, 10, 64)) #true #重置一下便可. model = Sequential() model.add(Embedding(vocab_siz, 64, input_length=maxword)) #獲得向量25000*maxword*64,這個地方原文寫錯了,說明他沒理解embed層 model.add(Flatten()) # 加入多層全鏈接 model.add(Dense(2000, activation='relu')) model.add(Dense(500, activation='relu')) model.add(Dense(200, activation='relu')) model.add(Dense(500, activation='relu')) # 最後一層輸進0~1之間的值,像lr那樣 model.add(Dense(1, activation='sigmoid')) # 計算 model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) print(model.summary()) #訓練 model.fit(x_train, y_train, validation_data=(x_test, y_test), batch_size=100, nb_epoch=2, verbose=1) score = model.evaluate(x_test, y_test) print(score) #%% ''' https://blog.csdn.net/zyp199301/article/details/70134203?locationNum=3&fps=1 學習這個 下載:https://www.gutenberg.org/files/11/11-0.txt 這個例子很奇葩,學習的不是單詞而是字符,因此預測效果確定很差,寫出來的東西都不必定 是英語 ''' #load ascii text and covert to lowercase filename = r"C:\Users\張博\Desktop\111.txt" raw_text = open(filename).read() raw_text = raw_text.lower() #預處理 chars = sorted(list(set(raw_text))) char_to_int = dict((c, i) for i, c in enumerate(chars)) int_to_char = dict((i, c) for i, c in enumerate(chars)) n_chars = len(raw_text) n_vocab = len(chars) print(n_chars) print(n_vocab) print(chars) # prepare the dataset of input to output pairs encoded as integers seq_length = 100 dataX = [] dataY = [] for i in range(0, n_chars - seq_length, 1): seq_in = raw_text[i:i + seq_length] seq_out = raw_text[i + seq_length] dataX.append([char_to_int[char] for char in seq_in]) dataY.append(char_to_int[seq_out]) n_patterns = len(dataX) print ("Total Patterns: ", n_patterns) import numpy # reshape X to be [samples, time steps, features] X = numpy.reshape(dataX, (n_patterns, seq_length, 1)) #這個切法就是每100個char,來預測下一個char是否是準. y=numpy.reshape(dataY,(len(dataY),1)) from math import sqrt from numpy import concatenate from matplotlib import pyplot from pandas import read_csv from pandas import DataFrame from pandas import concat from sklearn.preprocessing import MinMaxScaler from sklearn.preprocessing import LabelEncoder from sklearn.metrics import mean_squared_error from keras.models import Sequential from keras.layers import Dense from keras.layers import LSTM import keras from keras import regularizers from keras import optimizers print(y) print(X) model = Sequential() model.add(LSTM(256, input_shape=(X.shape[1], X.shape[2]))) model.add(Dense(y.shape[1], activation='softmax')) adam = optimizers.Adam(lr=0.001, clipnorm=.5) model.compile(loss='sparse_categorical_crossentropy', optimizer=adam) model.fit(X, y, nb_epoch=2, batch_size=128, verbose=1) #慢到崩潰,一個epoch 5分鐘 #這個學完都是loss=nan怎麼回事???????????? ''' 這個工具很重要 在天然語言處理上,深度學習在機器翻譯、自動問答、文本分類、情感分析、信息抽取、 序列標註、語法解析等領域都有普遍的應用。2013年底google發佈的word2vec工具, 能夠看作是深度學習在NLP領域的一個重要應用,雖然word2vec只有三層神經網絡,可是 已經取得很是好的效果。經過word2vec,能夠將一個詞表示爲詞向量,將文字數字化,更好 的讓計算機理解。使word2vec模型, 咱們能夠方便的找到同義詞或聯繫緊密的詞,或者意義相反的詞等。 ''' #%% ''' 學習這篇 https://www.cnblogs.com/Newsteinwell/p/6034747.html windows下沒法用word2vec,因此放棄 ''' #linux 提取標籤內容gerp便可.這個命令提取包含這個標籤包含的行. #cat news_tensite_xml.dat | iconv -f gbk -t utf-8 -c | grep "<content>" > corpus.txt import codecs a=open('C:/Users/張博/Desktop/news_sohusite_xml.smarty.dat',encoding='utf-8') a=a.readlines() out=[] for i in a: if '<content>' in i : out.append(i) print(out) a=''.join(out) #用join以後\ue什麼的字符就沒了 print(a) #%% ''' 學習這個:https://blog.csdn.net/qq_27492735/article/details/78596618 學習nltk框架 ''' import nltk ''' 抓取網頁 ''' import urllib.request response = urllib.request.urlopen('http://php.net/') html = response.read() ''' 清洗網頁 ''' from bs4 import BeautifulSoup import urllib.request response = urllib.request.urlopen('http://php.net/') html = response.read() soup = BeautifulSoup(html,"html5lib") text = soup.get_text(strip=True) from bs4 import BeautifulSoup import urllib.request response = urllib.request.urlopen('http://php.net/') html = response.read() soup = BeautifulSoup(html,"html5lib") text = soup.get_text(strip=True) tokens = text.split() ''' 每個tokens的詞頻統計,tokens表示的是一個單詞的意思,最後打印頻率表 ''' from bs4 import BeautifulSoup import urllib.request import nltk response = urllib.request.urlopen('http://php.net/') html = response.read() soup = BeautifulSoup(html,"html5lib") text = soup.get_text(strip=True) tokens = text.split() freq = nltk.FreqDist(tokens) for key,val in freq.items(): print (str(key) + ':' + str(val)) ''' 畫出頻率表 ''' freq.plot(20, cumulative=False) #%% ''' 處理停用詞:所謂停用詞就是那些虛詞,這些東西是要剔除的. ''' from nltk.corpus import stopwords a=stopwords.words('english') #打印停用詞 print(a) clean_tokens = list() sr = stopwords.words('english') for token in tokens: if token not in sr: clean_tokens.append(token) ''' 獲得了去除停用詞以後的詞頻 ''' freq = nltk.FreqDist(clean_tokens) for key,val in freq.items(): print (str(key) + ':' + str(val)) freq.plot(20, cumulative=False) #%% ''' 下面進行tokenize: 文本沒有Tokenize以前是沒法處理的,因此對文本進行Tokenize很是重要的。 token化過程意味着將大的部件分割爲小部件。 你能夠將段落tokenize成句子,將句子tokenize成單個詞,NLTK分別提供了 句子tokenizer和單詞tokenizer。 ''' #下面是橘子tokenize from nltk.tokenize import sent_tokenize mytext = "Hello Adam, how are you? I hope everything is going well. Today \ is a good day, see you dude." print(sent_tokenize(mytext)) #下面是單詞tokenize from nltk.tokenize import word_tokenize mytext = "Hello Mr. Adam, how are you? I hope everything is going well. \ Today is a good day, see you dude." print(word_tokenize(mytext)) #%% #切法語試試 from nltk.tokenize import sent_tokenize mytext = "Bonjour M. Adam, comment allez-vous? J'espère que tout va bien. Au\ jourd'hui est un bon jour." print(sent_tokenize(mytext,"french")) #%% from nltk.corpus import wordnet #缺包就用nltk.download()裝就好了 syn = wordnet.synsets("pain") print(type(syn)) print(syn) print(syn[0].definition()) print(syn[0].examples()) from nltk.corpus import wordnet syn = wordnet.synsets("NLP") print(syn[0].definition()) syn = wordnet.synsets("Python") print(syn[0].definition()) #%% #打印全部的同義詞 from nltk.corpus import wordnet synonyms = [] for syn in wordnet.synsets('Computer'): for lemma in syn.lemmas(): synonyms.append(lemma.name()) print(synonyms) #打印全部的反義詞 from nltk.corpus import wordnet antonyms = [] for syn in wordnet.synsets("small"): for l in syn.lemmas(): if l.antonyms(): antonyms.append(l.antonyms()[0].name()) print(antonyms) #%% #詞幹提取: from nltk.stem import PorterStemmer stemmer = PorterStemmer() print(stemmer.stem('working')) print(stemmer.stem('worked')) #%%變體還原:有過後詞幹提取是錯的,須要變體還原 from nltk.stem import WordNetLemmatizer print('原始單詞') print('increases') lemmatizer = WordNetLemmatizer() print('變體還原的結果') print(lemmatizer.lemmatize('increases')) from nltk.stem import PorterStemmer stemmer = PorterStemmer() print('詞幹提取的結果') print(stemmer.stem('increases')) #%% #改變詞性的變體還原 from nltk.stem import WordNetLemmatizer lemmatizer = WordNetLemmatizer() print(lemmatizer.lemmatize('playing', pos="v")) from nltk.stem import WordNetLemmatizer lemmatizer = WordNetLemmatizer() print(lemmatizer.lemmatize('playing', pos="v")) print(lemmatizer.lemmatize('playing', pos="n")) print(lemmatizer.lemmatize('playing', pos="a")) print(lemmatizer.lemmatize('playing', pos="r")) ''' 總結: 詞幹提取不會考慮語境,這也是爲何詞幹提取比變體還原快且準確度低的緣由。 我的認爲,變體還原比詞幹提取更好。單詞變體還原返回一個真實的單詞,即便它不是同一個 單詞,也是同義詞,但至少它是一個真實存在的單詞。 '''
批量把文件名修改爲爲編號.py
#下面代碼就是把路徑path裏面的內容都修改爲他前面3個字符.由於這個例子裏面正好前3個字符是編號 import os path='E:/計算機網絡原理精講視頻教程/視頻' name=os.listdir(path) for temp in name: new_name=temp[:3] new_name=str(int(new_name)) os.rename(path+'/'+temp,path+'/'+new_name+) import os path='E:/計算機網絡原理精講視頻教程/視頻' name=os.listdir(path) for temp in name: new_name=temp os.rename(path+'/'+temp,path+'/'+'課程'+new_name+'.mp4') #因此說要讓播放器自動生成列表須要一個名稱後面加數字才行.