рд╢реБрдн рджрд┐рди, рджреЛрд╕реНрддреЛрдВ! рдореИрдВ рдЖрдкрдХреЗ рд▓рд┐рдП рдореВрд▓ рд▓реЗрдЦ рдХрд╛ рдПрдХ рд╢реМрдХрд┐рдпрд╛ рдЕрдиреБрд╡рд╛рдж рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реВрдВ: рдлрд╛рд╕реНрдЯрдЯреЗрдХреНрд╕реНрдЯ: рдорд╛рд░рд┐рдпрд╛ рдореЗрд╕реНрдЯреНрд░реЗ рджреНрд╡рд╛рд░рд╛ рдХреЛрдб рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрджрдо ред
рдПрдХ рдЫреЛрдЯреА рд╕реА рдЪреЗрддрд╛рд╡рдиреА: рдЙрдкрд▓рдмреНрдз рдХрд░рд╛рдИ рдЧрдИ рдХреБрдЫ рдЬрд╛рдирдХрд╛рд░реА рд▓реЗрдЦрдХ рдХреЗ рд╕рдордп рдФрд░ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рдкрд╛рд░рд┐рдд рд╣реЛрдиреЗ рдХреЗ рдХрд╛рд░рдг рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рдЪ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреА рд╣реИред рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ, рдХреЛрдИ рднреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╡рд╛рдВрдЫрдиреАрдп рд╣реЛрдЧреА!
рдЖрдкрдиреЗ рдЧреНрд░рдВрдереЛрдВ рдХреЗ рдЕрдкрдиреЗ рд╢рд░реАрд░ рдХреЛ рд╡реЗрдХреНрдЯрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП FastText рдЬреИрд╕реЗ рдЙрдкрдХрд░рдг рдХрд╛ рд╕рд╛рдордирд╛ рдХрд┐рдпрд╛ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ FastText рдЖрдкрдХреЗ рд╡рд░реНрдЧреАрдХрд░рдг рд╕реЗ рднреА рдирд┐рдкрдЯ рд╕рдХрддрд╛ рд╣реИ? рдпрд╛ рд╢рд╛рдпрдж рд╡реЗ рдЬрд╛рдирддреЗ рдереЗ, рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╡рд╣ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рд╡рд╣ рдЗрд╕реЗ рдХреИрд╕реЗ рдХрд░рддрд╛ рд╣реИ? рдЪрд▓реЛ рдЗрд╕реЗ рдЕрдВрджрд░ рд╕реЗ рджреЗрдЦреЗрдВ ... рдореЗрд░рд╛ рдорддрд▓рдм рд╣реИ, рд╕реНрдХреНрд░реАрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗред
FastText рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдлреЗрд╕рдмреБрдХ рдЯреАрдо рджреНрд╡рд╛рд░рд╛ рдЧреНрд░рдВрдереЛрдВ рдХреЛ рд╡рд░реНрдЧреАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╢рдмреНрдж рдПрдореНрдмреЗрдбрд┐рдВрдЧ рдХреЛ рдкреНрд░рд╢рд┐рдХреНрд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднреА рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЪреВрдВрдХрд┐ рдЙрд╕ рд╕рдордп рдЬрдм рдлрд╛рд╕реНрдЯрдЯреЗрдХреНрд╕ рд╕рднреА рдХреЗ рд▓рд┐рдП рд╕реБрд▓рдн рдЙрддреНрдкрд╛рдж рдмрди рдЧрдпрд╛ (2016), рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЗрд╕рдХреА рдЕрдЪреНрдЫреА рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдЧрддрд┐ рдФрд░ рдЙрддреНрдХреГрд╖реНрдЯ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рдХрд╛рд░рдг рд╡реНрдпрд╛рдкрдХ рд░реВрдк рд╕реЗ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИредрдЖрдзрд┐рдХрд╛рд░рд┐рдХ рдкреНрд░рд▓реЗрдЦрди (рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╣реА рджреБрд░реНрд▓рдн) рдХреЛ рдкрдврд╝рддреЗ рд╣реБрдП, рдореБрдЭреЗ рдПрд╣рд╕рд╛рд╕ рд╣реБрдЖ рдХрд┐ рдЗрд╕рдореЗрдВ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХрд╛ рдПрдХ рдмрдбрд╝рд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╢рд╛рдорд┐рд▓ рд╣реИ рдЬреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкрд╛рд░рджрд░реНрд╢реА рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдпрд╣ рдХреНрдпрд╛ рдЦрд╛рддрд╛ рд╣реИред рдореИрдВрдиреЗ рд░рдЪрдирд╛рдХрд╛рд░реЛрдВ рдХреЗ рдореБрдЦреНрдп рд▓реЗрдЦ рдФрд░ рдПрдирдПрд▓рдкреА рдореЗрдВ рд╕реНрдЯреИрдирдлреЛрд░реНрдб рдбреАрдк рд▓рд░реНрдирд┐рдВрдЧ рдХреЛрд░реНрд╕ рдкрд░ рдПрдХ рддреНрд╡рд░рд┐рдд рдирдЬрд╝рд░ рдбрд╛рд▓рдХрд░ рдкрдврд╝рдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ред рдЗрд╕ рд╕рд╛рд░реА рдЦреБрд╢реА рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ, рдореИрдВрдиреЗ рдХреЗрд╡рд▓ рдкреНрд░рд╢реНрди рдмрдврд╝рд╛рдПред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП: рдХрд┐ рд╕реНрдЯреИрдирдлреЛрд░реНрдб рдХреЗ рд╡реНрдпрд╛рдЦреНрдпрд╛рди рдХреЗ рджреМрд░рд╛рди рдФрд░ рд▓реЗрдЦ рдХреЗ рдПрдХ рд╣рд┐рд╕реНрд╕реЗ рдореЗрдВ рд╡реЗ рдПрди-рдЧреНрд░рд╛рдо рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╡реЗ рдЕрдкрдиреЗ рдЖрд╡реЗрджрди рдореЗрдВ рдХреЛрдИ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рдирд╣реАрдВ рдХрд╣рддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдореЗрдВ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдмрд╛рд▓реНрдЯреА рд╣реА рд╢рд╛рдорд┐рд▓ рд╣реИ рдЬрд┐рд╕ рдкрд░ рдХреЗрд╡рд▓ "рдХрдВрдЯреЗрдирд░ (рдмрд╛рд▓реНрдЯреА) рдХреА рд╕рдВрдЦреНрдпрд╛" рдЬреИрд╕реА рдзреНрд╡рдирд┐ рд╣реЛрддреА рд╣реИред рдЗрди рдПрди-рдЧреНрд░рд╛рдореЛрдВ рдХреА рдЧрдгрдирд╛ рдХреИрд╕реЗ рдХреА рдЬрд╛рддреА рд╣реИ? рдмрд╛рд▓реНрдЯреА? рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ ... рдПрдХ рд╡рд┐рдХрд▓реНрдк рд╢реЗрд╖ рд╣реИ, рдХреЛрдб рджреЗрдЦреЗрдВGitHub редрд╕рднреА рдЕрдЪреНрдЫреЗ рдХреЛ рджреЗрдЦрдиреЗ рдХреЗ рдмрд╛рдж, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрддрд╛ рдЪрд▓рд╛
- рдлрд╛рд╕реНрдЯрдЯреЗрдХреНрд╕реНрдЯ рдЖрддреНрдорд╡рд┐рд╢реНрд╡рд╛рд╕ рдХреЗ рд╕рд╛рде рдПрди-рдЧреНрд░рд╛рдо рдЕрдХреНрд╖рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдХрд┐ рдПрди-рдЧреНрд░рд╛рдо рд╢рдмреНрджреЛрдВ рдХреЗ рд╕рдорд╛рди рд╣реА рд╣реИред
- рдлрд╛рд╕реНрдЯрдЯреЗрдХреНрд╕реНрдЯ рдорд▓реНрдЯреАрд╕реНрдХреЗрд▓реНрд╕ рд╡рд░реНрдЧреАрдХрд░рдг рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдкрд╣рд▓реА рдмрд╛рд░ рдЗрддрдирд╛ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред
- рдореЙрдбрд▓ рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛
рдореЙрдбрд▓ рдкрд░рд┐рдЪрдп
рдбреЗрд╡рд▓рдкрд░реНрд╕ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦреЗ рдЧрдП рдПрдХ рд▓реЗрдЦ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдореЙрдбрд▓ рдПрдХ рдЫрд┐рдкреА рд╣реБрдИ рдкрд░рдд рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд░рд▓ рддрдВрддреНрд░рд┐рдХрд╛ рдиреЗрдЯрд╡рд░реНрдХ рд╣реИред рд╢рдмреНрдж рдмреИрдЧ (BOW) рджреНрд╡рд╛рд░рд╛ рджрд░реНрд╢рд╛рдпрд╛ рдЧрдпрд╛ рдкрд╛рда рдкрд╣рд▓реА рдкрд░рдд рд╕реЗ рд╣реЛрдХрд░ рдЧреБрдЬрд░рд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдпрд╣ рд╢рдмреНрдж рдПрдореНрдмреЗрдб рдореЗрдВ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдмрд╛рдж, рдкрд░рд┐рдгрд╛рдореА рдПрдореНрдмреЗрдбрд┐рдВрдЧ рдкреВрд░реЗ рдкрд╛рда рдкрд░ рдФрд╕рддрди рд╣реЛрддреА рд╣реИ рдФрд░ рдкреВрд░реЗ рдкрд╛рда рдореЗрдВ рд▓рд╛рдЧреВ рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдХреЗрд╡рд▓ рдПрдХ рдХреЗ рд▓рд┐рдП рдХрдо рд╣реЛ рдЬрд╛рддреА рд╣реИред рдЫрд┐рдкреА рд╣реБрдИ рдкрд░рдд рдореЗрдВ, рд╣рдо рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рджреНрд╡рд╛рд░рд╛ n_words * рдордВрдж рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ , рдЬрд╣рд╛рдВ рдордВрдж рдПрдореНрдмреЗрдбрд┐рдВрдЧ рдХрд╛ рдЖрдХрд╛рд░ рд╣реИ, рдФрд░ n_words рдкрд╛рда рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╢рдмреНрджрдХреЛрд╢ рдХрд╛ рдЖрдХрд╛рд░ рд╣реИред рдФрд╕рдд рдХреЗ рдмрд╛рдж, рд╣рдореЗрдВ рдПрдХ рдПрдХрд▓ рд╡реЗрдХреНрдЯрд░ рдорд┐рд▓рддрд╛ рд╣реИ рдЬреЛ рдПрдХ рд▓реЛрдХрдкреНрд░рд┐рдп рдХреНрд▓рд╛рд╕рд┐рдлрд╛рдпрд░рд┐рдлрд╛рдпрд░ рд╕реЗ рдЧреБрдЬрд░рддрд╛ рд╣реИ: рд╕реЙрдлреНрдЯрдореИрдХреНрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИрдкрд╣рд▓реА рдкрд░рдд рдХреЗ рдЗрдирдкреБрдЯ рдбреЗрдЯрд╛ рдХреЗ рд░реИрдЦрд┐рдХ рдореИрдкрд┐рдВрдЧ (рд░реВрдкрд╛рдВрддрд░рдг) рдХреЗ рд▓рд┐рдП рдЕрдВрддрд┐рдоред рдЖрдпрд╛рдо рдордВрдж рдХрд╛ рдПрдХ рдореИрдЯреНрд░рд┐рдХреНрд╕ * n_output рдПрдХ рд░реИрдЦрд┐рдХ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ , рдЬрд╣рд╛рдВ n_output рд╣рдорд╛рд░реА рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХрдХреНрд╖рд╛рдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╣реИред рдореВрд▓ рд▓реЗрдЦ рдореЗрдВ, рдЕрдВрддрд┐рдо рд╕рдВрднрд╛рд╡рдирд╛ рдХреЛ рд▓реЙрдЧ-рд╕рдВрднрд╛рд╡рдирд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ :
рдЬрд╣рд╛рдВ:- x_n n-gram рдореЗрдВ рдПрдХ рд╢рдмреНрдж рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рд╣реИред
- рдФрд░ рдпрд╣ рдПрдХ рд▓реБрдХ_рдЕрдк рдореИрдЯреНрд░рд┐рдХреНрд╕ рд╣реИ рдЬреЛ рдХрд┐рд╕реА рд╢рдмреНрдж рдХреЗ рдПрдореНрдмреЗрдбрд┐рдВрдЧ рдХреЛ рдирд┐рдХрд╛рд▓рддрд╛ рд╣реИред
- рдпрд╣ рдЖрдЙрдЯрдкреБрдЯ рдХрд╛ рдПрдХ рд░реИрдЦрд┐рдХ рдкрд░рд┐рд╡рд░реНрддрди рд╣реИред
- f рд╕реАрдзреЗ рд╕реЙрдлреНрдЯрдореИрдХреНрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╕реНрд╡рдпрдВ рдХрд░рддрд╛ рд╣реИред
рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░ рд╕рдм рдХреБрдЫ рдЗрддрдирд╛ рдмреБрд░рд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА рдЖрдЗрдП рдХреЛрдб рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓рддреЗ рд╣реИрдВ:рдПрдХ рд╡рд┐рдЪрд╛рд░ рдЕрдиреБрд╡рд╛рдж рдХреЗ рд░реВрдк рдореЗрдВ рдХреЛрдб
рд╕реНрд░реЛрдд рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдлрд╝рд╛рдЗрд▓ рдЬрд┐рд╕реЗ рд╣рдо рдЕрдкрдиреЗ рдХреНрд▓рд╛рд╕рд┐рдлрд╝рд╛рдпрд░ рдХреЗ рд▓рд┐рдП рдЖрд╡реЗрджрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрд╕реЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдлрд╝реЙрд░реНрдо рдХрд╛ рдкрд╛рд▓рди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП: __label__0 (рдкрд╛рда)редрдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ:__label__cat рдпрд╣ рдЪреЛрд░реА рдмрд┐рд▓реНрд▓рд┐рдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИред__label__dog рдпрд╣ рдкрд╛рда рдХреБрддреНрддреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИредрд╕реНрд░реЛрдд рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЯреНрд░реЗрди рдлрд╝рдВрдХреНрд╢рди рдХреЗ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ ред рдЯреНрд░реЗрди рдлрд╝рдВрдХреНрд╢рди рдкреНрд░рд╛рд░рдВрдн рдФрд░ рдмрд╛рдж рдореЗрдВ рдбрд┐рдХреНрдЯреНрд░реА_ рд╡реЗрд░рд┐рдПрдмрд▓ рдХреЗ рднрд░рдиреЗ рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ редvoid FastText::train(const Args args) {
args_ = std::make_shared<Args>(args);
dict_ = std::make_shared<Dictionary>(args_);
if (args_->input == "-") {
throw std::invalid_argument("Cannot use stdin for training!");
}
std::ifstream ifs(args_->input);
if (!ifs.is_open()) {
throw std::invalid_argument(
args_->input + " cannot be opened for training!");
}
dict_->readFromFile(ifs);
рдбрд┐рдХреНрд╢рдирд░реА_ рдбрд┐рдХреНрд╢рдирд░реА рдХреНрд▓рд╛рд╕ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИред
Dictionary::Dictionary(std::shared_ptr<Args> args) : args_(args),
word2int_(MAX_VOCAB_SIZE, -1), size_(0), nwords_(0), nlabels_(0),
ntokens_(0), pruneidx_size_(-1) {}
рд╕реНрд░реЛрдд рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╡рд╛рдХреНрдпреЛрдВ рдХреЛ рдкрдврд╝рдиреЗ рдФрд░ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рджреЛ рд╡реИрдХреНрдЯрд░ рднрд░рддреЗ рд╣реИрдВ:- рд╢рдмреНрдж_ рдЬрд┐рд╕рдореЗрдВ рдкрд╛рда рд╕реЗ рдирд┐рдХрд╛рд▓реЗ рдЧрдП рдЕрджреНрд╡рд┐рддреАрдп рд╢рдмреНрдж рд╣реИрдВ
- word2int_ рдореЗрдВ рдЕрдкрдиреА рд╕реНрдерд┐рддрд┐ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдкреНрд░рддреНрдпреЗрдХ рд╢рдмреНрдж рдХреЗ рд▓рд┐рдП рд╣реИрд╢ рдпреБрдХреНрдд words_ рд╡реЗрдХреНрдЯрд░ ред рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдореИрдЯреНрд░рд┐рдХреНрд╕ рдП рдХреЗ рдПрдореНрдмреЗрдбрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдЦреЛрдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛
рд╢рдмреНрдж_
рд╡реЗрдХреНрдЯрд░ рдореЗрдВ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХреЗ рдЙрджрд╛рд╣рд░рдг рд╣реИрдВред рдЬрд┐рдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рд▓реЗрдмрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рд╢рдмреНрдж рдкреНрд░рдХрд╛рд░ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЙрдирдХреЗ рдкрд╛рд╕ рдХреЙрд▓ рдХрд╛ рдПрдХ рдХрд╛рдЙрдВрдЯрд░ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдПрдХ рдЙрдк- рдлрд╝реАрд▓реНрдб рдлрд╝реАрд▓реНрдб рднреА рд╣реИ , рд▓реЗрдХрд┐рди рд╣рдо рдЗрд╕реЗ рдереЛрдбрд╝рд╛ рдЖрдЧреЗ рджреЗрдЦреЗрдВрдЧреЗредstruct entry {
std::string word;
int64_t count;
entry_type type;
std::vector<int32_t> subwords;
};
рд╢рдмреНрдж рдпрд╛ рдЯреИрдЧ рдХреЛ рд╢рдмреНрдж 2int_ рдЪрд░ рдореЗрдВ рдЬреЛрдбрд╝рдХрд░ , рдЯрдХрд░рд╛рд╡ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдХрднреА рднреА рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╢рдмреНрджреЛрдВ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рдирдореЗрдВ рдПрдХ рд╣реА рд╕реВрдЪрдХрд╛рдВрдХ рд╣реЛрддрд╛ рд╣реИред рд╡рд╣рд╛рдБ рдмрд╕ рдХреЛрдИ рдирд╣реАрдВ рд╣реЛрдЧрд╛int32_t Dictionary::find(const std::string& w, uint32_t h) const {
int32_t word2intsize = word2int_.size();
int32_t id = h % word2intsize;
while (word2int_[id] != -1 && words_[word2int_[id]].word != w) {
id = (id + 1) % word2intsize;
}
return id;
}
int32_t Dictionary::find(const std::string& w) const {
return find(w, hash(w));
}
void Dictionary::add(const std::string& w) {
int32_t h = find(w);
ntokens_++;
if (word2int_[h] == -1) {
entry e;
e.word = w;
e.count = 1;
e.type = getType(w);
words_.push_back(e);
word2int_[h] = size_++;
} else {
words_[word2int_[h]].count++;
}
}
рджреЛрдиреЛрдВ рд╡реИрдХреНрдЯрд░ рдХреЛ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдХрдо рд╕реЗ рдХрдо рдПрдХ рдмрд╛рд░ рдЙрд▓реНрд▓реЗрдЦрд┐рдд рд╢рдмреНрдж рдФрд░ рдЯреИрдЧ рд╢рд╛рдорд┐рд▓ рд╣реИрдВред рд╣рдо рдЙрд╕ рд╣рд┐рд╕реНрд╕реЗ рдкрд░ рдЬрд╛рдиреЗ рдХреЗ рдмрд╛рдж рдЬрд╣рд╛рдВ рд╣рдо рд░реАрдбрдлреНрд░реЙрдордлрд╛рдЗрд▓ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ initNgrams рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ ред рд╣рдо рд▓рдЧрднрдЧ рдПрди-рдЧреНрд░рд╛рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд░рд╣рд╕реНрдпрд╡рд╛рджреА рдХреЗ рдкрд╛рд╕ рдЧрдПред
void Dictionary::readFromFile(std::istream& in) {
std::string word;
int64_t minThreshold = 1;
while (readWord(in, word)) {
add(word);
if (ntokens_ % 1000000 == 0 && args_->verbose > 1) {
std::cerr << "\rRead " << ntokens_ / 1000000 << "M words" << std::flush;
}
if (size_ > 0.75 * MAX_VOCAB_SIZE) {
minThreshold++;
threshold(minThreshold, minThreshold);
}
}
threshold(args_->minCount, args_->minCountLabel);
initTableDiscard();
initNgrams();
InitNgrams
рдлрд╝рдВрдХреНрд╢рди рдПрди-рдЧреНрд░рд╛рдо рд╡рд░реНрдгреЛрдВ рдХреЗ рд╕рднреА рд╕рдВрдпреЛрдЬрдиреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдПрдирдЧреНрд░рд╛рдо рд╡реЗрдХреНрдЯрд░ рдореЗрдВ рдЬреЛрдбрд╝рддрд╛ рд╣реИ ред рдЕрдВрдд рдореЗрдВ, рдПрди-рдЧреНрд░рд╛рдо рдХреЗ рд▓рд┐рдП рд╕рднреА рд╣реИрд╢ рдХреА рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИ рдФрд░ рдПрдирдЧреНрд░рд╛рдо рд╡реЗрдХреНрдЯрд░ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ , рдЬрд┐рд╕рд╕реЗ рдмрд╛рд▓реНрдЯреА рдХрд╛ рдЖрдХрд╛рд░ рдмрдирддрд╛ рд╣реИ ред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдПрди-рдЧреНрд░рд╛рдо рдХреЗ рд╡рд░реНрдгреЛрдВ рдХреЗ рд╣реИрд╢ рдХреЛ рдПрди-рдЧреНрд░рд╛рдо рд╢рдмреНрджреЛрдВ рдХреЗ рд╣реИрд╢ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдмрд╛рдж рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИред рдирддреАрдЬрддрди, рдЙрдирдХреЗ рд╕реВрдЪрдХрд╛рдВрдХ рд╢рдмреНрджреЛрдВ рдХреЗ рд╕реВрдЪрдХрд╛рдВрдХреЛрдВ рдХреЗ рд╕рд╛рде рдУрд╡рд░рд▓реИрдк рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рдУрд╡рд░рд▓реИрдк рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВредрд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдкрд╛рда рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рд╢рдмреНрдж рдХреЗ рд▓рд┐рдП, рдЖрдк рд╕рдм - рдкрд╛рд╕рд╡рд░реНрдб ... рдПрди-рдЧреНрд░рд╛рдо рд╡рд░реНрдг рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ редрдПрдВрдмреЗрдбрд┐рдВрдЧ рдореИрдЯреНрд░рд┐рдХреНрд╕ A рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ:- рдкрд╛рда рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рд╢рдмреНрджрдХреЛрд╢ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рд╢рдмреНрдж рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рд░рдВрднрд┐рдХ nwords_ рд▓рд╛рдЗрдиреЗрдВ рдЬрд┐рдирдореЗрдВ рдПрдореНрдмреЗрдбрд┐рдВрдЧ рд╣реИред
- рдкреНрд░рддреНрдпреЗрдХ рдПрди-рдЧреНрд░рд╛рдо рдХреЗ рдкрд╛рддреНрд░реЛрдВ рдХреЗ рд▓рд┐рдП рдПрдореНрдмреЗрдбрд┐рдВрдЧ рд╡рд╛рд▓реА рд▓рд╛рдЗрдиреЛрдВ рдХреА рдмрд╛рд▓реНрдЯреА рдХрд╛ рдкрд╛рд▓рди рдХрд░реЗрдВ
void Dictionary::initNgrams() {
for (size_t i = 0; i < size_; i++) {
std::string word = BOW + words_[i].word + EOW;
words_[i].subwords.clear();
words_[i].subwords.push_back(i);
if (words_[i].word != EOS) {
computeSubwords(word, words_[i].subwords);
}
}
}
void Dictionary::computeSubwords(const std::string& word,
std::vector<int32_t>& ngrams) const {
for (size_t i = 0; i < word.size(); i++) {
std::string ngram;
if ((word[i] & 0xC0) == 0x80) continue;
for (size_t j = i, n = 1; j < word.size() && n <= args_->maxn; n++) {
ngram.push_back(word[j++]);
while (j < word.size() && (word[j] & 0xC0) == 0x80) {
ngram.push_back(word[j++]);
}
if (n >= args_->minn && !(n == 1 && (i == 0 || j == word.size()))) {
int32_t h = hash(ngram) % args_->bucket;
pushHash(ngrams, h);
}
}
}
}
void Dictionary::pushHash(std::vector<int32_t>& hashes, int32_t id) const {
if (pruneidx_size_ == 0 || id < 0) return;
if (pruneidx_size_ > 0) {
if (pruneidx_.count(id)) {
id = pruneidx_.at(id);
} else {
return;
}
}
hashes.push_back(nwords_ + id);
}
рдЗрд╕рд▓рд┐рдП рд╣рдордиреЗ рд░рд╣рд╕реНрдпрдордп рдПрди-рдЧреНрд░рд╛рдо рдкрд╛рддреНрд░реЛрдВ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ред рдЕрдм рд╢рдмреНрджреЛрдВ рдХреЗ рдПрди-рдЧреНрд░рд╛рдо рд╕реЗ рдирд┐рдкрдЯрддреЗ рд╣реИрдВред рдЯреНрд░реЗрдирдлрд╝рдВрдХреНрд╢рди рдкрд░ рд▓реМрдЯрддреЗ рд╣реБрдП , рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: if (args_->pretrainedVectors.size() != 0) {
loadVectors(args_->pretrainedVectors);
} else {
input_ = std::make_shared<Matrix>(dict_->nwords()+args_->bucket, args_->dim);
input_->uniform(1.0 / args_->dim);
}
if (args_->model == model_name::sup) {
output_ = std::make_shared<Matrix>(dict_->nlabels(), args_->dim);
} else {
output_ = std::make_shared<Matrix>(dict_->nwords(), args_->dim);
}
output_->zero();
startThreads();
рдпрд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдВ рдПрдореНрдмреЗрдбрд┐рдВрдЧ рдореИрдЯреНрд░рд┐рдХреНрд╕ рдП рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдпрд╣ рдЗрдВрдЧрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдЕрдЧрд░ pretrainedVectors рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдЪрд░ рдкреВрд░реНрдг рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдРрд╕рд╛ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХреЛ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд╕рдВрдЦреНрдпрд╛ -1 / рдордВрдж рдФрд░ 1 / рдордВрдж рдХреЗ рд╕рд╛рде рдкреНрд░рд╛рд░рдВрдн рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ , рдЬрд╣рд╛рдВ рдордВрдж рд╣рдорд╛рд░реЗ рдПрдореНрдмреЗрдбрд┐рдВрдЧ рдХрд╛ рдЖрдХрд╛рд░ рд╣реИред рдореИрдЯреНрд░рд┐рдХреНрд╕ рдП рдХрд╛ рдЖрдпрд╛рдо ( n_words_ + рдмрд╛рд▓реНрдЯреА ; рдордВрдж ), рдЕрд░реНрдерд╛рдд рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рд╢рдмреНрдж рдХреЗ рд▓рд┐рдП рдпреЗ рд╕рднреА рдПрдореНрдмреЗрдбрд┐рдВрдЧ рд╕реЗрдЯ рдХрд░рдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВред рдЗрд╕ рдЪрд░рдг рдореЗрдВ рдЖрдЙрдЯрдкреБрдЯ рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рднреА рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИредрдирддреАрдЬрддрди, рд╣рдореЗрдВ рд╡рд╣ рд╣рд┐рд╕реНрд╕рд╛ рдорд┐рд▓рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рд╣рдо рдЕрдкрдиреЗ рдореЙрдбрд▓ рдХрд╛ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред
void FastText::trainThread(int32_t threadId) {
std::ifstream ifs(args_->input);
utils::seek(ifs, threadId * utils::size(ifs) / args_->thread);
Model model(input_, output_, args_, threadId);
if (args_->model == model_name::sup) {
model.setTargetCounts(dict_->getCounts(entry_type::label));
} else {
model.setTargetCounts(dict_->getCounts(entry_type::word));
}
const int64_t ntokens = dict_->ntokens();
int64_t localTokenCount = 0;
std::vector<int32_t> line, labels;
while (tokenCount_ < args_->epoch * ntokens) {
real progress = real(tokenCount_) / (args_->epoch * ntokens);
real lr = args_->lr * (1.0 - progress);
if (args_->model == model_name::sup) {
localTokenCount += dict_->getLine(ifs, line, labels);
supervised(model, lr, line, labels);
} else if (args_->model == model_name::cbow) {
localTokenCount += dict_->getLine(ifs, line, model.rng);
cbow(model, lr, line);
} else if (args_->model == model_name::sg) {
localTokenCount += dict_->getLine(ifs, line, model.rng);
skipgram(model, lr, line);
}
if (localTokenCount > args_->lrUpdateRate) {
tokenCount_ += localTokenCount;
localTokenCount = 0;
if (threadId == 0 && args_->verbose > 1)
loss_ = model.getLoss();
}
}
if (threadId == 0)
loss_ = model.getLoss();
ifs.close();
}
рдХреЛрдб рдХреЗ рдЗрд╕ рднрд╛рдЧ рдореЗрдВ рджреЛ рдореБрдЦреНрдп рдмрд┐рдВрджреБ рд╣реИрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, getLine рдлрд╝рдВрдХреНрд╢рди рдбрд┐рдХреНрдЯреЗрдб_ рд╡реЗрд░рд┐рдПрдмрд▓ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ ред рджреВрд╕рд░рд╛, рдкрд░реНрдпрд╡реЗрдХреНрд╖рд┐рдд рдлрд╝рдВрдХреНрд╢рди рдХрд╣рд▓рд╛рддрд╛ рд╣реИ редint32_t Dictionary::getLine(std::istream& in,
std::vector<int32_t>& words,
std::vector<int32_t>& labels) const {
std::vector<int32_t> word_hashes;
std::string token;
int32_t ntokens = 0;
reset(in);
words.clear();
labels.clear();
while (readWord(in, token)) {
uint32_t h = hash(token);
int32_t wid = getId(token, h);
entry_type type = wid < 0 ? getType(token) : getType(wid);
ntokens++;
if (type == entry_type::word) {
addSubwords(words, token, wid);
word_hashes.push_back(h);
} else if (type == entry_type::label && wid >= 0) {
labels.push_back(wid - nwords_);
}<source lang="cpp">
if (token == EOS) break;
}
addWordNgrams(words, word_hashes, args_->wordNgrams);
return ntokens;
}
рдЙрдкрд░реЛрдХреНрдд рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ, рд╣рдо рдЗрдирдкреБрдЯ рдбреЗрдЯрд╛ рд╕реЗ рдЧреНрд░рдВрдереЛрдВ рдХреЛ рдкрдврд╝рддреЗ рд╣реИрдВ, рдкреНрд░рддреНрдпреЗрдХ рд╢рдмреНрдж рдХреЗ рд▓рд┐рдП рд╕реВрдЪрдХ рдХрд╛ рдирд┐рд░реНрдзрд╛рд░рдг рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рдмрд╛рдж word2int_ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд░рддреЗ рд╣реИрдВ ред рд╣рдо рдПрди-рдЧреНрд░рд╛рдо рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рдЬреЛ рдЗрди рд╢рдмреНрджреЛрдВ рдХреЛ рд╢рдмреНрдж рдЪрд░ рдореЗрдВ рдмрдирд╛рддреЗ рд╣реИрдВ , рдЬреИрд╕рд╛ рдХрд┐ рдХреЛрдб рдореЗрдВ рд╕рдВрдХреЗрдд рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдФрд░ рдЕрдВрдд рдореЗрдВ, рд╣рдо рд╕реАрдзреЗ рд▓реЗрдмрд▓ рд╡реЗрдХреНрдЯрд░ рдореЗрдВ рд▓реЗрдмрд▓ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ редрдЙрдирдХреЗ рд▓рд┐рдП рдмрдирд╛рдП рдЧрдП рд╡реИрдХреНрдЯрд░ рд╕реЗ рд╕реАрдзреЗ рдкрд╛рда (рдХреЙрд░реНрдкрд╕ рд╕реЗ рд╡рд╛рдХреНрдп) рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкрдврд╝рдиреЗ рдФрд░ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдореЗрдВ рдПрди-рдЧреНрд░рд╛рдо рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреЛрдб рдХрд╛ рдПрдХ рд╣рд┐рд╕реНрд╕рд╛ рдорд┐рд▓рддрд╛ рд╣реИред рдпрд╣ addWordNgrams рдлрд╝рдВрдХреНрд╢рди рд╣реИ редvoid Dictionary::addWordNgrams(std::vector<int32_t>& line,
const std::vector<int32_t>& hashes,
int32_t n) const {
for (int32_t i = 0; i < hashes.size(); i++) {
uint64_t h = hashes[i];
for (int32_t j = i + 1; j < hashes.size() && j < i + n; j++) {
h = h * 116049371 + hashes[j];
pushHash(line, h % args_->bucket);
}
}
}
рд╣рдо рдЖрдЧреЗ рджреЗрдЦрддреЗ рд╣реИрдВред рд╣реИрд╢ рдЪрд░ рдкрд╛рда рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рд╢рдмреНрдж рдХреЗ рд▓рд┐рдП рд╣реИрд╢ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╣реИ, рдЬрд╣рд╛рдВ рд▓рд╛рдЗрди рдореЗрдВ рд╡рд╛рдХреНрдп рдореЗрдВ рд╢рдмреНрджреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдФрд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдПрди-рдЧреНрд░рд╛рдо рдХреА рд╕рдВрдЦреНрдпрд╛ рд╣реЛрддреА рд╣реИред рдкреИрд░рд╛рдореАрдЯрд░ n рдкреИрд░рд╛рдореАрдЯрд░ рд╢рдмреНрджNgrams рд╣реИ рдФрд░ рд╢рдмреНрджреЛрдВ рдХреЗ рдПрди-рдЧреНрд░рд╛рдо рдХреА рдЕрдзрд┐рдХрддрдо рд▓рдВрдмрд╛рдИ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИред рд╢рдмреНрджреЛрдВ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдПрди-рдЧреНрд░рд╛рдо рдХреЛ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рд╣реИрд╢ рдХреА рдЧрдгрдирд╛ рдПрдХ рдкреБрдирд░рд╛рд╡рд░реНрддреА рд╕реВрддреНрд░ рджреНрд╡рд╛рд░рд╛ рдХреА рдЬрд╛рддреА рд╣реИ
ред рдпрд╣ рд╕реВрддреНрд░ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рд▓рд╛рдЧреВ FNV рд╣реИрд╢ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╣реИ: рдпрд╣ рд╢рдмреНрджреЛрдВ рдХреЗ рдПрди-рдЧреНрд░рд╛рдо рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рд╢рдмреНрдж рдХрд╛ рд╣реИрд╢ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЬреЛрдбрд╝рддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЕрджреНрд╡рд┐рддреАрдп рд╣реИрд╢ рдХрд╛ рдПрдХ рд╕реЗрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдирддреАрдЬрддрди, рдпрд╣ рдорд╛рди (рдХрд╛рдлреА рдмрдбрд╝рд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ) рдореЙрдбреБрд▓реЛ рдкреНрд░рд╕рд╛рд░рд┐рдд рд╣реЛрддрд╛ рд╣реИредрдЗрд╕ рдкреНрд░рдХрд╛рд░, рдПрди-рдЧреНрд░рд╛рдо рд╢рдмреНрджреЛрдВ рдХреА рдЧрдгрдирд╛ рд▓рдЧрднрдЧ рдЙрд╕реА рддрд░рд╣ рд╕реЗ рдХреА рдЬрд╛рддреА рд╣реИ рдЬреИрд╕реЗ рдХрд┐ рдПрди-рдЧреНрд░рд╛рдо рд╡рд░реНрдг, рд▓реЗрдХрд┐рди рдереЛрдбрд╝реЗ рдЕрдВрддрд░ рдХреЗ рд╕рд╛рде - рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╢рдмреНрдж рдирд╣реАрдВ рд╣реИред рдХрдорд╛рд▓ рдХреА рдЪрд╛рд▓ рд╣реИредрд╡рд╛рдХреНрдп рдкрдврд╝рдиреЗ рдХреЗ рдмрд╛рдж, рдкрд░реНрдпрд╡реЗрдХреНрд╖рд┐рдд рдлрд╝рдВрдХреНрд╢рди рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ ред рдпрджрд┐ рдСрдлрд╝рд░ рдореЗрдВ рдХрдИ рдЯреИрдЧ рд╣реИрдВ, рддреЛ рд╣рдо рдмреЗрддрд░рддреАрдм рдврдВрдЧ рд╕реЗ рдЙрдирдореЗрдВ рд╕реЗ рдПрдХ рдХрд╛ рдЪрдпрди рдХрд░рддреЗ рд╣реИрдВред
void FastText::supervised(
Model& model,
real lr,
const std::vector<int32_t>& line,
const std::vector<int32_t>& labels) {
if (labels.size() == 0 || line.size() == 0) return;
std::uniform_int_distribution<> uniform(0, labels.size() - 1);
int32_t i = uniform(model.rng);
model.update(line, labels[i], lr);
}
рдФрд░ рдЕрдВрдд рдореЗрдВ, рдореЙрдбрд▓ рдЕрдкрдбреЗрдЯ рдлрд╝рдВрдХреНрд╢рдиредvoid Model::computeHidden(const std::vector<int32_t>& input, Vector& hidden) const {
assert(hidden.size() == hsz_);
hidden.zero();
for (auto it = input.cbegin(); it != input.cend(); ++it) {
if(quant_) {
hidden.addRow(*qwi_, *it);
} else {
hidden.addRow(*wi_, *it);
}
}
hidden.mul(1.0 / input.size());
}
void Model::update(const std::vector<int32_t>& input, int32_t target, real lr) {
assert(target >= 0);
assert(target < osz_);
if (input.size() == 0) return;
computeHidden(input, hidden_);
if (args_->loss == loss_name::ns) {
loss_ += negativeSampling(target, lr);
} else if (args_->loss == loss_name::hs) {
loss_ += hierarchicalSoftmax(target, lr);
} else {
loss_ += softmax(target, lr);
}
nexamples_ += 1;
if (args_->model == model_name::sup) {
grad_.mul(1.0 / input.size());
}
for (auto it = input.cbegin(); it != input.cend(); ++it) {
wi_->addRow(grad_, *it, 1.0);
}
}
рдкрд░реНрдпрд╡реЗрдХреНрд╖рд┐рдд
рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдЧреБрдЬрд░рдиреЗ рд╡рд╛рд▓реЗ рдЗрдирдкреБрдЯ рдЪрд░ рдореЗрдВ рд╡рд╛рдХреНрдп рдХреЗ рдЙрдирдХреЗ рд╕рднреА рдШрдЯрдХреЛрдВ (рд╢рдмреНрджреЛрдВ, рд╢рдмреНрджреЛрдВ рдХреЗ рдПрди-рдЧреНрд░рд╛рдо рдФрд░ рдкреНрд░рддреАрдХреЛрдВ) рдХреЗ рд╕реВрдЪрдХрд╛рдВрдХреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рд╣реЛрддреА рд╣реИред рд▓рдХреНрд╖реНрдп рдПрдХ рд╡рд░реНрдЧ рдХреЛ рдЖрдЙрдЯрдкреБрдЯ рдкрд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдирд╛ рд╣реИред рдХрдореНрдкреНрдпреВрдЯреЗрдб рдлрд╝рдВрдХреНрд╢рди рдЗрдирдкреБрдЯ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдШрдЯрдХ рдХреЗ рд▓рд┐рдП wi_ рдореИрдЯреНрд░рд┐рдХреНрд╕ рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рдЦреЛрдЬрдХрд░ рдФрд░ рдФрд╕рдд ( addRow рдХреЛ рдЙрдирдХреЗ рдЖрдХрд╛рд░ рд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдФрд░ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ) рдХреЗ рд▓рд┐рдП рд╕рднреА рдПрдореНрдмреЗрдбрд┐рдВрдЧ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ ред Hide_ рд╡реЗрдХреНрдЯрд░ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж , рдЙрдиреНрд╣реЗрдВ рд╕реЙрдлреНрдЯрдореИрдХреНрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рдХреНрд░рд┐рдпрдг рдХреЗ рд▓рд┐рдП рднреЗрдЬреЗрдВ рдФрд░ рдПрдХ рд▓реЗрдмрд▓ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВредрдХреЛрдб рдХрд╛ рдпрд╣ рдЦрдВрдб рд╕реЙрдлреНрдЯрдореИрдХреНрд╕ рд╕рдХреНрд░рд┐рдпрдг рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рджрд┐рдЦрд╛рддрд╛ рд╣реИ ред рд▓реЙрдЧ-рд▓реЙрд╕ рдХреА рдЧрдгрдирд╛ рднреА рдХреА рдЬрд╛рддреА рд╣реИ редvoid Model::computeOutputSoftmax(Vector& hidden, Vector& output) const {
if (quant_ && args_->qout) {
output.mul(*qwo_, hidden);
} else {
output.mul(*wo_, hidden);
}
real max = output[0], z = 0.0;
for (int32_t i = 0; i < osz_; i++) {
max = std::max(output[i], max);
}
for (int32_t i = 0; i < osz_; i++) {
output[i] = exp(output[i] - max);
z += output[i];
}
for (int32_t i = 0; i < osz_; i++) {
output[i] /= z;
}
}
void Model::computeOutputSoftmax() {
computeOutputSoftmax(hidden_, output_);
}
real Model::softmax(int32_t target, real lr) {
grad_.zero();
computeOutputSoftmax();
for (int32_t i = 0; i < osz_; i++) {
real label = (i == target) ? 1.0 : 0.0;
real alpha = lr * (label - output_[i]);
grad_.addRow(*wo_, i, alpha);
wo_->addRow(hidden_, i, alpha);
}
return -log(output_[target]);
}
рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЗ рдЙрдкрдпреЛрдЧ рд╕реЗ, рд╣рдореЗрдВ рд╢рдмреНрджреЛрдВ рдФрд░ рд╡рд░реНрдгреЛрдВ рдХреЗ рдПрди-рдЧреНрд░рд╛рдо рдХреЗ рдЖрдХрд╛рд░ рдореЗрдВ рд╡реГрджреНрдзрд┐ рдирд╣реАрдВ рдорд┐рд▓реЗрдЧреАред рд╡рд┐рдХрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рдЙрдкрд▓рдмреНрдз рдмрд╛рд▓реНрдЯрд┐рдпреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╕реЗ рд╕реАрдорд┐рдд рд╣реИ редрдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, FastText N-gr рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддреЗ рд╣реИрдВ:- рд╣рд┐рд░рди = 2,000,000; рд╢рдмреНрджрдЧреНрд░рд╛рдо> 1 рдпрд╛ рдЕрдзрд┐рдХрддрдо> 0
- рдордВрдж = резрежреж
- n_output = 2
- n_words = 500000
рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░, рд╣рдореЗрдВ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░ рдорд┐рд▓рддреЗ рд╣реИрдВ
рдмрд╣реБрдд рдЕрдзрд┐рдХ, рдпрд╣ рдирд╣реАрдВ рд╣реИ?) рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рд╕рд░рд▓ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рднреА рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХрд╛рдлреА рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИрдВ, рдЬреЛ рдХрд┐ рдЧрд╣рди рд╢рд┐рдХреНрд╖рдг рд╡рд┐рдзрд┐рдпреЛрдВ рдХреА рдмрд╣реБрдд рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреНрд░рдо рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП 2_000_000 рдХреЗ рд▓рд┐рдП рд▓реА рдЧрдИ N-gr рдХреА рд╕рдВрдЦреНрдпрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдХреБрдЫ рд╣рд╛рдЗрдкрд░рдкрд░рдореЗрдЯрд░реНрд╕, рдЬреИрд╕реЗ рдмрд╛рд▓реНрдЯреА рдпрд╛ рд╕реИрдВрдкрд▓рд┐рдВрдЧ рдереНрд░реЗрд╢реЛрд▓реНрдб рдХреЛ рдЯреНрдпреВрди рдХрд░рдХреЗ рдореЙрдбрд▓ рдХреА рдЬрдЯрд┐рд▓рддрд╛ рдХреЛ рдХрдо рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИредрдХреБрдЫ рд▓рд┐рдВрдХ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ:research.fb.com/fasttextarxiv.org/pdf/1607.01759.pdf рдФрд░ arxiv.org/pdf/1607.04606v1.pdfwww.youtube.com/watch?v=isPiE-DBagM&index=5&list=PLU40WLOO894/zp94 (47:39 рд╕реЗ)