丝袜人妻一区二区三区_少妇福利无码视频_亚洲理论片在线观看_一级毛片国产A级片

當(dāng)前位置:首頁 > 話題廣場(chǎng) > 攻略專題 > 游戲問答

用強(qiáng)化學(xué)習(xí)玩轉(zhuǎn)Chrome暗藏的小恐龍?zhí)惶?,這兒有一份教程

夏乙郭福頭下凹非寺

量子比特生產(chǎn)|公眾號(hào)QbitAI

什么!沒有連接到互聯(lián)網(wǎng)!

明明是網(wǎng)絡(luò)狀態(tài),為什么是我想訪問的頁面

沒有!法律!打吧!打開它!

冷靜下來。

作為一個(gè)Google Chrome瀏覽器的用戶,當(dāng)你看到上面那個(gè)頁面時(shí),不要沮喪。換個(gè)角度一想,墻內(nèi)還能有更多的Play時(shí)間哦~

你有沒有注意到畫面里那個(gè)小恐龍?

當(dāng)你遇到打不開網(wǎng)頁的時(shí)候,只需要再點(diǎn)擊一下這個(gè)頁面(手機(jī)),或者按下空格(電腦),隨著小恐龍輕輕一跳——

一個(gè)新世界開啟了。

這個(gè)“恐龍?zhí)惶逼鋵?shí)是藏在Chrome瀏覽器里好多年的一個(gè)彩蛋。小恐龍是一只霸王龍(T-Rex)。

2013年Chrome開始用這個(gè)小恐龍的圖像代替令人煩惱的404頁面。2014年秋天,這只恐龍被正式改造成一個(gè)橫版小游戲。以彩蛋的方式隱藏在新版Chrome瀏覽器里。

吶,如果你還不知道這個(gè)彩蛋,可以抓緊試一試。比方說——

  • 訪問一個(gè)不翻墻就看不了的網(wǎng)頁

  • 或者直接輸入:chrome://dino

  • 或者訪問: (需翻墻)

后來,這個(gè)小游戲也成了不少AI練手的對(duì)象。

比如最近就有人在YouTube上貼了一段視頻,展示了他如何用神經(jīng)網(wǎng)絡(luò)+遺傳算法,讓一個(gè)AI系統(tǒng)獨(dú)秀于瀏覽器之中。

我們把精華的部分截取了一下,就是下面這段視頻。

動(dòng)圖版:

速度已經(jīng)快到飛起

總而言之,一句話,這個(gè)AI能輕松玩到2萬多分……

你能玩到幾分?大概率是玩不到這個(gè)成績的吧。畢竟在c頁面上,人類玩家的歷史最高分是18842。

不過,上傳這段視頻的作者,并沒有詳細(xì)公布他用的方法,當(dāng)然也沒有給出一個(gè)開源的地址。不過不要緊,也有別人公開分享了更多細(xì)節(jié)。

例如,GitHub上就有一個(gè)開源的代碼“IAMDinosaur”,同樣也是利用神經(jīng)網(wǎng)絡(luò)+遺傳算法,來搞定恐龍?zhí)惶?/p>

地址在此:

美中不足,上面這個(gè)項(xiàng)目也沒有配上太詳盡的解讀。然而好消息是,最近有個(gè)國外的小哥Ravi Munde,列了一份非常詳盡的教程。

這個(gè)教程用的方法是強(qiáng)化學(xué)習(xí)中的Q-learning,比較適合入門練手,而且對(duì)硬件的要求不高。

量子位搬運(yùn)這份教程如下。

Q-learning了解/復(fù)習(xí)一下

對(duì)動(dòng)物來說,強(qiáng)化學(xué)習(xí)的能力是與生俱來的。拿兒童學(xué)步來舉例,如果小朋友努力的邁出第一步,就會(huì)獲得父母的鼓勵(lì)——可能是鼓掌叫好,也可能是一塊糖;但如果小朋友堅(jiān)決不肯學(xué)習(xí)走路,那父母就不會(huì)給它糖吃了。強(qiáng)化學(xué)習(xí)就是依照這類激勵(lì)行為而設(shè)置的。

而在這個(gè)游戲中,對(duì)我們的AI小恐龍來說,強(qiáng)化學(xué)習(xí)需要讓他在無監(jiān)督的情況下,先認(rèn)識(shí)到做出不同動(dòng)作的結(jié)果,并且以獲得高分為最高激勵(lì)。

一個(gè)典型的強(qiáng)化學(xué)習(xí)閉環(huán)

Ravi Munde用Q-learning模擬了一個(gè)特殊函數(shù),這個(gè)函數(shù)驅(qū)動(dòng)AI在不同狀況下做出正確的選擇。

Q-learning是強(qiáng)化學(xué)習(xí)的一種無模型實(shí)現(xiàn),根據(jù)Q值對(duì)每個(gè)狀態(tài)進(jìn)行判斷此時(shí)如果采取行動(dòng),能獲得怎樣的獎(jiǎng)勵(lì)。一個(gè)樣本Q表讓我們了解數(shù)據(jù)的結(jié)構(gòu)。在恐龍跑酷游戲中,狀態(tài)是當(dāng)前的游戲截圖,能采取的行動(dòng)是跳或不跳[0,1]

一個(gè)樣本Q表

Ravi Munde決定用深度神經(jīng)網(wǎng)絡(luò)來決定小恐龍何時(shí)起跳,而且要在最簡單的強(qiáng)化學(xué)習(xí)實(shí)現(xiàn)基礎(chǔ)上,引入不同參數(shù)來輔助它。

缺乏已標(biāo)記的數(shù)據(jù)讓強(qiáng)化學(xué)習(xí)非常不穩(wěn)定。為了獲得適用于這個(gè)游戲的數(shù)據(jù),Munde小哥決定,先讓小恐龍自己瞎跳幾千次,把每個(gè)動(dòng)作的反饋記下來,然后從數(shù)據(jù)中隨機(jī)挑選一些來訓(xùn)練模型。

但之后,Munde小哥發(fā)現(xiàn),他訓(xùn)練了一個(gè)倔強(qiáng)的模型——模型堅(jiān)定的認(rèn)為,跳,一定比不跳好。所以,為了讓模型在訓(xùn)練時(shí)能在跳與不跳之間多嘗試一下,他引入了一個(gè)函數(shù)?來決定行動(dòng)的隨機(jī)性,然后再逐漸減小它的值來削減隨機(jī)性,最終讓模型去選擇最有可能獲得獎(jiǎng)勵(lì)的行動(dòng)。

贊譽(yù)分布(Credit Assignment)問題可能會(huì)讓模型陷入混亂——目前獲得的獎(jiǎng)勵(lì)究竟來自于過去的哪個(gè)行為呢?在恐龍跑酷游戲中,小恐龍?zhí)桨肟罩泻鬅o法再次跳躍,但模型可能會(huì)在恐龍?zhí)幱诎肟罩袝r(shí)發(fā)出跳躍指令,這種情況就讓恐龍非常容易砸到仙人掌上。

在這種情況下,“砸到仙人掌上”這個(gè)負(fù)反饋實(shí)際上是此前上一次做出跳躍決定的結(jié)果,而不是剛剛恐龍?jiān)诎肟罩袝r(shí)做出的跳躍結(jié)果所導(dǎo)致的。

在面臨這種問題的情況下,可以引入貼現(xiàn)因子(Discount Factor)γ來決定模型做出動(dòng)作時(shí)看得多遠(yuǎn)。γ間接解決了贊譽(yù)分布問題,在這個(gè)游戲中,當(dāng)γ=0.99時(shí),模型認(rèn)識(shí)到在無障礙時(shí)隨便跳會(huì)導(dǎo)致真的遇到障礙時(shí)自己正在半空中,無法繼續(xù)跳躍。

除了這兩個(gè)參數(shù)之外,后面就幾乎不需要任何參數(shù)了。

#game parameters GAMMA = 0.99 # decay rate of past observations original 0.99 OBSERVATION = 50000. # timesteps to observe before training EXPLORE = 100000 # frames over which to anneal epsilon FINAL_EPSILON = 0.0001 # final value of epsilon INITIAL_EPSILON = 0.1 # starting value of epsilon REPLAY_MEMORY = 50000 # number of previous transitions to remember BATCH = 32 # size of minibatch FRAME_PER_ACTION = 1

你需要準(zhǔn)備的是

  • Python 3.6

  • Selenium

  • OpenCV

  • PIL

  • Chromium driver for Selenium

  • Keras

略微解釋一下這幾個(gè)工具。

構(gòu)建這個(gè)AI模型,需要用Python編程。而游戲是用JavaScript寫成的。所以,得借助一些工具才能更好地溝通。

Selenium是一種流行的瀏覽器自動(dòng)化工具,用于向?yàn)g覽器發(fā)送操作指令,以及獲取各種游戲參數(shù)。

接口的事情搞定了,還得想辦法獲得游戲截屏。用Selenium也行,但是速度很慢,截屏和處理一次大約得1秒鐘。

用PIL和OpenCV能夠更好地完成截屏和圖像預(yù)處理,可以達(dá)到5fps的幀率。你可能覺得還是慢,但已經(jīng)足夠?qū)Ω哆@個(gè)游戲了。

游戲模塊

下面這個(gè)模塊,實(shí)現(xiàn)了Python和瀏覽器(使用Selenium)的溝通。

''' * Game class: Selenium interfacing between the python and browser * __init__(): Launch the broswer window using the attributes in chrome_options * get_crashed() : return true if the agent as crashed on an obstacles. Gets javascript variable from game decribing the state * get_playing(): true if game in progress, false is crashed or paused * restart() : sends a signal to browser-javascript to restart the game * press_up(): sends a single to press up get to the browser * get_score(): gets current game score from javascript variables. * pause(): pause the game * resume(): resume a paused game if not crashed * end(): close the browser and end the game ''' class Game: def __init__(self,custom_config=True): chrome_options = Options() c("disable-infobars") = webdriver.Chrome(executable_path = chrome_driver_path,chrome_options=chrome_options) .set_window_position(x=-10,y=0) .set_window_size(200, 300) .get(game_url)) #modifying game before training if custom_config: .execute_script("Runner.con;) def get_crashed(self): return .execute_script("return Runner.in;) def get_playing(self): return .execute_script("return Runner.in;) def restart(self): .execute_script("Runner.in()") )# no actions are possible # for 0.25 sec after game starts, # skip learning at this time and make the model wait def press_up(self): .find_element_by_tag_name("body").send_key) def get_score(self): score_array = .execute_script("return Runner.in;) score = ''.join(score_array) # the javascript object is of type array with score in the formate[1,0,0] which is 100. return int(score) def pause(self): return .execute_script("return Runner.in()") def resume(self): return .execute_script("return Runner.in()") def end(self): .close()

恐龍智能體模塊

這個(gè)模塊在游戲模塊的幫助下,用于控制小恐龍的動(dòng)作。

class DinoAgent: def __init__(self,game): #takes game as input for taking actions = game; (); #to start the game, we need to jump once (.5) # no action can be performed for the first time when game starts def is_running(self): return .get_playing() def is_crashed(self): return .get_crashed() def jump(self): .press_up() def duck(self): .press_down()

游戲狀態(tài)模塊

神經(jīng)網(wǎng)絡(luò)直接使用這個(gè)模塊,來執(zhí)行操作并獲取新的狀態(tài)。

''' get_state(): accepts an array of actions, performs the action on the agent returns : new state, reward and if the game ended. ''' class Game_sate: def __init__(self,agent,game): = agent = game def get_state(self,actions): score = .get_score() reward = 0.1*score/10 # dynamic reward calculation is_over = False #game over if actions[1] == 1: #else do nothing .jump() reward = 0.1*score/11 image = grab_screen() if .is_crashed(): .restart() reward = -11/score is_over = True return image, reward, is_over #return the Experience tuple

預(yù)處理

游戲修改

原始的游戲相對(duì)復(fù)雜,比如游戲速度會(huì)逐漸加快,障礙物會(huì)改變,還會(huì)出現(xiàn)云朵、星星、地面紋理等。一次同時(shí)學(xué)習(xí)這么多東西會(huì)消耗大量時(shí)間,甚至在訓(xùn)練過程中引入不必要的噪音。

為此作者修改了游戲的源代碼、簡化局面,去除了一些視覺元素(云、歷史最佳成績等),還有讓恐龍的奔跑速度保持不變。

原圖

修改后

圖像處理

原始截圖的分辨率為1200×300,包含三個(gè)通道。作者計(jì)劃使用4個(gè)連續(xù)的屏幕截圖作為模型的單一輸入,也就是1200×300×3×4。

問題是,這個(gè)小哥只有一個(gè)i7的CPU可用,所以他的電腦沒辦法在處理這個(gè)尺寸輸入的同時(shí)玩游戲。所以,還得繼續(xù)用OpenCV的庫調(diào)正截圖大小、裁剪等。最終輸入圖像大小為40×20像素,單通道,并用Canny突出顯示邊緣。

def grab_screen(_driver = None): #bbox = region of interest on the entire screen screen = np.array(bbox=(40,180,440,400))) image = process_img(screen)#processing image as required return image def process_img(image): #game is already in grey scale canvas, canny to get only edges and reduce unwanted objects(clouds) # resale image dimensions image = cv2.resize(image, (0,0), fx = 0.15, fy = 0.10) #crop out the dino agent from the frame image = image[2:38,10:50] #img[y:y+h, x:x+w] image = cv2.Canny(image, threshold1 = 100, threshold2 = 200) #apply the canny edge detection return image

然后,堆疊4張圖創(chuàng)建單個(gè)輸入,也就是:40×20×4。請(qǐng)注意,這里小恐龍也裁減掉了,因?yàn)檎麄€(gè)學(xué)習(xí)過程,只需要知道障礙物和與邊緣的距離即可。

模型架構(gòu)

現(xiàn)在輸入有了,用模型輸出來玩游戲的方法也有了,只差模型架構(gòu)。

小哥選擇把3個(gè)卷積層壓平,連接到一個(gè)512神經(jīng)元的全連接層(dense layer)上。池化層直接被砍掉了,這個(gè)東西在圖像分類問題上很有用,但是玩Dino的時(shí)候神經(jīng)網(wǎng)絡(luò)只需要知道障礙物的位置,池化層就起不了什么作用了。

多層網(wǎng)絡(luò)架構(gòu)

這個(gè)模型的輸出,形狀和可能的操作數(shù)量一樣。模型會(huì)預(yù)測(cè)各種操作的Q值,也叫discounted future reward,然后我們選數(shù)值最高的那個(gè)。

下面這段代碼,就能召喚一個(gè)用TensorFlow后端的Keras來搭建的模型:

#model hyper parameters LEARNING_RATE = 1e-4 img_rows , img_cols = 40,20 img_channels = 4 #We stack 4 frames ACTIONS = 2 def buildmodel(): print("Now we build the model") model = Sequential() model.add(Conv2D(32, (8, 8), strides=(4, 4), padding='same',input_shape=(img_cols,img_rows,img_channels))) #20*40*4 model.add(Activation('relu')) model.add(Conv2D(64, (4, 4), strides=(2, 2), padding='same')) model.add(Activation('relu')) model.add(Conv2D(64, (3, 3), strides=(1, 1), padding='same')) model.add(Activation('relu')) model.add(Flatten()) model.add(Dense(512)) model.add(Activation('relu')) model.add(Dense(ACTIONS)) adam = Adam(lr=LEARNING_RATE) model.compile(loss='mse',optimizer=adam) print("We finish building the model") return model

開始訓(xùn)練

接下來,就是見證奇跡的時(shí)刻~~

也就是用一段代碼來訓(xùn)練模型,這段代碼的任務(wù)是:

  • 從無操作開始,得到初始狀態(tài)initial state(s_t)

  • 觀察玩游戲的過程,代碼中的OBSERVATION表示步數(shù)

  • 預(yù)測(cè)一個(gè)操作的效果

  • 在Replay Memory中存儲(chǔ)經(jīng)驗(yàn)

  • 訓(xùn)練階段,從Replay Memory里隨機(jī)選擇一組,用它來訓(xùn)練模型

  • 如果game over了,就重開一局

更詳細(xì)的,可以看這段自帶注釋的代碼:

''' Parameters: * model => Keras Model to be trained * game_state => Game State module with access to game environment and dino * observe => flag to indicate wherther the model is to be trained(weight updates), else just play ''' def trainNetwork(model,game_state): # store the previous observations in replay memory D = deque() #load from file system # get the first state by doing nothing do_nothing = np.zeros(ACTIONS) do_nothing[0] =1 #0 => do nothing, #1=> jump x_t, r_0, terminal = game_(do_nothing) # get next step after performing the action s_t = np.stack((x_t, x_t, x_t, x_t), axis=2).reshape(1,20,40,4) # stack 4 images to create placeholder input reshaped 1*20*40*4 OBSERVE = OBSERVATION epsilon = INITIAL_EPSILON t = 0 while (True): #endless running loss = 0 Q_sa = 0 action_index = 0 r_t = 0 #reward at t a_t = np.zeros([ACTIONS]) # action at t #choose an action epsilon greedy if random.random() <= epsilon: #randomly explore an action print("----------Random Action----------") action_index = random.randrange(ACTIONS) a_t[action_index] = 1 else: # predict the output q = model.predict(s_t) #input a stack of 4 images, get the prediction max_Q = np.argmax(q) # chosing index with maximum q value action_index = max_Q a_t[action_index] = 1 # o=> do nothing, 1=> jump #We reduced the epsilon (exploration parameter) gradually if epsilon > FINAL_EPSILON and t > OBSERVE: epsilon -= (INITIAL_EPSILON - FINAL_EPSILON) / EXPLORE #run the selected action and observed next state and reward x_t1, r_t, terminal = game_(a_t) last_time = () x_t1 = x_(1, x_[0], x_[1], 1) #1x20x40x1 s_t1 = np.append(x_t1, s_t[:, :, :, :3], axis=3) # append the new image to input stack and remove the first one # store the transition in D D.append((s_t, action_index, r_t, s_t1, terminal)) D.popleft() if len(D) > REPLAY_MEMORY #only train if done observing; sample a minibatch to train on trainBatc(D, BATCH)) if t > OBSERVE s_t = s_t1 t = t + 1 print("TIMESTEP", t, "/ EPSILON", epsilon, "/ ACTION", action_index, "/ REWARD", r_t,"/ Q_MAX " , np.max(Q_sa), "/ Loss ", loss)

將這個(gè)模型用到從Replay Memory里隨機(jī)選擇的一批上:

def trainBatch(minibatch): for i in range(0, len(minibatch)): loss = 0 inputs = np.zeros((BATCH, [1], [2], [3])) #32, 20, 40, 4 targets = np.zero[0], ACTIONS)) #32, 2 state_t = minibatch[i][0] # 4D stack of images action_t = minibatch[i][1] #This is action index reward_t = minibatch[i][2] #reward at state_t due to action_t state_t1 = minibatch[i][3] #next state terminal = minibatch[i][4] #wheather the agent died or survided due the action inputs[i:i + 1] = state_t targets[i] = model.predict(state_t) # predicted q values Q_sa = model.predict(state_t1) #predict q values for next step if terminal: targets[i, action_t] = reward_t # if terminated, only equals reward else: targets[i, action_t] = reward_t + GAMMA * np.max(Q_sa) loss += model.train_on_batch(inputs, targets)

主體方法

調(diào)用下面的方法,就能啟動(dòng)上面的訓(xùn)練流程:

#argument: observe, only plays if true, else trains def playGame(observe=False): game = Game() dino = DinoAgent(game) game_state = Game_sate(dino,game) model = buildmodel() trainNetwork(model,game_state)

結(jié)果

這個(gè)模型,小哥用一周的時(shí)間訓(xùn)練了200萬幀,其中前100萬幀用來調(diào)整游戲參數(shù)修補(bǔ)bug,后100萬幀真正用來訓(xùn)練。

現(xiàn)在,這個(gè)模型的最好成績是265分。從下面的得分和損失變化圖里,能看出模型的loss在后100萬幀逐漸穩(wěn)定,比較低,但是會(huì)隨時(shí)間波動(dòng)。

游戲得分

后100幀的損失(loss)

目前的局限

雖然這個(gè)模型后來表現(xiàn)還算可以了,但比人類還是差了一大截。

當(dāng)然,別忘了這個(gè)小哥比較窮,他只有一個(gè)i7的CPU。

他認(rèn)為,模型學(xué)得還不夠快,得分還不夠高,要怪這樣幾個(gè)因素:一是因?yàn)橛肅PU來學(xué)習(xí),它總是掉幀;二是供這個(gè)AI來玩耍的圖像實(shí)在是太小了,只有40×20,在當(dāng)前的模型架構(gòu)下就可能導(dǎo)致了特征的損失,還拖慢了學(xué)習(xí)速度。

如果改用GPU,說不定……

相關(guān)鏈接

用GPU究竟會(huì)不會(huì)改善,你們可以拿這份代碼來試試:

原文地址:

One More Thing

其實(shí)嘛,讓AI搞定小恐龍這件事,本質(zhì)上跟讓AI搞定Flappy Bird是一樣的。如果你想深入研究一下這件事,這里再推薦兩篇。

機(jī)器學(xué)習(xí)玩轉(zhuǎn)Flappy Bird全書:六大“流派”從原理到代碼

使用神經(jīng)網(wǎng)絡(luò)+遺傳算法玩轉(zhuǎn)Flappy Bird | 教程

就醬~

— 完 —

誠摯招聘

量子位正在招募編輯/記者,工作地點(diǎn)在北京中關(guān)村。期待有才氣、有熱情的同學(xué)加入我們!相關(guān)細(xì)節(jié),請(qǐng)?jiān)诹孔游还娞?hào)(QbitAI)對(duì)話界面,回復(fù)“招聘”兩個(gè)字。

量子位 QbitAI · 頭條號(hào)簽約作者

?'?' ? 追蹤AI技術(shù)和產(chǎn)品新動(dòng)態(tài)

1.《用強(qiáng)化學(xué)習(xí)玩轉(zhuǎn)Chrome暗藏的小恐龍?zhí)惶?,這兒有一份教程》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息知識(shí),僅代表作者本人觀點(diǎn),與本網(wǎng)站無關(guān),侵刪請(qǐng)聯(lián)系頁腳下方聯(lián)系方式。

2.《用強(qiáng)化學(xué)習(xí)玩轉(zhuǎn)Chrome暗藏的小恐龍?zhí)惶?,這兒有一份教程》僅供讀者參考,本網(wǎng)站未對(duì)該內(nèi)容進(jìn)行證實(shí),對(duì)其原創(chuàng)性、真實(shí)性、完整性、及時(shí)性不作任何保證。

3.文章轉(zhuǎn)載時(shí)請(qǐng)保留本站內(nèi)容來源地址,http://f99ss.com/gl/3166572.html

上一篇

IE瀏覽器崩潰怎么辦?IE瀏覽器總是崩潰的解決方法

關(guān)于瀏覽器怎么實(shí)現(xiàn)心跳,你需要知道這些WebSocket協(xié)議深入探究

關(guān)于瀏覽器怎么實(shí)現(xiàn)心跳,你需要知道這些WebSocket協(xié)議深入探究

瀏覽器怎么實(shí)現(xiàn)心跳相關(guān)介紹,一、內(nèi)容概述 網(wǎng)絡(luò)套接字的出現(xiàn)使瀏覽器能夠進(jìn)行實(shí)時(shí)雙向通信。 本文由淺入深,介紹了WebSocket如何建立連接、交換數(shù)據(jù)的細(xì)節(jié),以及數(shù)據(jù)幀的格式。此外,還簡要介紹了針對(duì)WebSocket的安全攻擊,...

瀏覽器怎么實(shí)現(xiàn)心跳?總結(jié)很全面速看!瀏覽器與服務(wù)器的消息通信

瀏覽器怎么實(shí)現(xiàn)心跳?總結(jié)很全面速看!瀏覽器與服務(wù)器的消息通信

瀏覽器怎么實(shí)現(xiàn)心跳相關(guān)介紹,最近工作中遇到了一個(gè)場(chǎng)景,商家需要在商家后面實(shí)時(shí)了解是否有新訂單,在某些情況下有幾種。(威廉莎士比亞,溫斯頓,工作)這個(gè)要求類似于日常生活中使用QQ或微信時(shí)的新信息通知,只要有新信息,就需要通知。商家...