নিউরাল নেটওয়ার্কের জন্য অ্যাঙ্গেল ডেটা এনকোডিং


20

আমি একটি নিউরাল নেটওয়ার্ক প্রশিক্ষণ দিচ্ছি (বিশদটি গুরুত্বপূর্ণ নয়) যেখানে লক্ষ্যযুক্ত ডেটা কোণগুলির একটি ভেক্টর (0 এবং 2 * পাই এর মধ্যে) হয়। আমি কীভাবে এই ডেটাটিকে এনকোড করব সে বিষয়ে পরামর্শ খুঁজছি। আমি বর্তমানে যা চেষ্টা করছি তা এখানে (সীমিত সাফল্যের সাথে):

1) 1-অফ-সি এনকোডিং: আমি সম্ভাব্য কোণগুলিকে 1000 বা এতগুলি পৃথক কোণে বিন্যাস করি এবং তারপরে প্রাসঙ্গিক সূচকে একটি 1 স্থাপন করে একটি নির্দিষ্ট কোণকে নির্দেশ করি। এটির সাথে সমস্যাটি হ'ল নেটওয়ার্কটি কেবল সমস্ত 0 এর আউটপুট শিখতে শেখে (যেহেতু এটি প্রায় সঠিকভাবে)।

2) সাধারণ স্কেলিং: আমি নেটওয়ার্ক আউটপুট পরিসর ([0,1]) থেকে [0,2 * পিআই] করে দিয়েছি। এখানে সমস্যাটি হ'ল কোণগুলিতে স্বাভাবিকভাবেই একটি বৃত্তাকার টপোলজি থাকে (যেমন 0.0001 এবং 2 * পাই আসলে একে অপরের ঠিক পাশের অংশে থাকে)। এই জাতীয় এনকোডিংয়ের সাথে, সেই তথ্যটি হারিয়ে যায়।

কোন পরামর্শ প্রশংসা হবে!


1
নেটওয়ার্কটি সমস্ত জিরো আউটপুট দেওয়ার ক্ষেত্রে আপনার সমস্যা হবে না, আপনি যদি কোনও সফটম্যাক্স আউটপুট স্তর ব্যবহার করেন - যা আপনার সাধারণত করা উচিত, যদি আপনি একটি ক্যাটাগরিয়াল (অর্থাত্ 1-অফ-সি) আউটপুট ব্যবহার করছেন।
লিন্ডন হোয়াইট

7
একটি বিশুদ্ধরূপে ফটকামূলক এনকোডিং ধারণা (আমি দেখেছি এটা না কাজ করেছি অথবা এটি পরীক্ষিত, কিন্তু আমি লাগছিল না) সঙ্কেতাক্ষরে লিখা আপনার কোণ (হয় ) একজোড়া হিসাবে । আমি মনে করি তখন এটি এবং মতো সমস্ত মানগুলির সাথে একে অপরের নিকটে একটি ক্রমাগত মানচিত্র হবে । আমি মনে করি আমি এটির একটি ডেমো তৈরি করতে এবং এটি পরীক্ষা করে দেখতে পারি। θ ( পাপ ( θ ) , কোস ( θ ) ) 0 2 πθθ(sin(θ),cos(θ))02π
লিন্ডন হোয়াইট

আমি এই সম্পর্কে আরও কিছু ভাবছিলাম, এবং আমি মনে করি এটি সম্ভবত আপনার ক্ষতি ফাংশনেই থাকতে পারে। আমি একগুচ্ছ জিনিস চেষ্টা করতে চাই আমি ডেমো তৈরি করেছি, তবে এটিতে পরীক্ষা শেষ করিনি। আগামীকাল কিছুক্ষণ পরীক্ষামূলক সমর্থন সহ একটি বিশদ উত্তরের প্রত্যাশা করুন। (যদি আমি না করি তবে আমাকে জাহির করুন)
লিন্ডন হোয়াইট

আমি বর্তমানে কোনও সফটম্যাক্স স্তর ব্যবহার করছি না এবং সম্ভবত এটিই সমস্যা। আমি সুযোগ পেলে আজ তা বাস্তবায়ন করব! আপনার (কোস, পাপ) ধারণাটি খুব আকর্ষণীয় এবং আমি বিশেষত পছন্দ করি যে এটি স্বয়ংক্রিয়ভাবে এই পরিসীমাটিকে [-1,1] এর মধ্যে রাখে (আপনি যদি তানহীন অ্যাক্টিভেশন ফাংশন নিয়ে কাজ করছেন তবে ভাল)। আমি আপনার ফলাফলগুলি দেখার অপেক্ষায় রয়েছি 1
এরি হারমান

একটি দ্রুত আপডেট: আমি একটি সফটম্যাক্স স্তর প্রয়োগ করার চেষ্টা করেছি, এবং এখনও আমার ভাগ্য নেই। সমস্যাটি, আমি মনে করি, এই সমস্যাটির জন্য এটি প্রয়োজনীয় যে ডেটাটির "কৌনিকতা" কোনওভাবে এনকোডিংয়ে উপস্থাপন করা উচিত। একটি শ্রেণিবদ্ধ এনকোডিং সহ, লক্ষ্য ডেটার টপোলজি হারিয়ে যায়। অতএব 0.5 * পাই এবং 0.05 * পাই এর ত্রুটি নেটওয়ার্কের সাথে একই দেখাচ্ছে (এটি উভয়কেই ভুল শ্রেণিবদ্ধকরণ হিসাবে দেখায়)।
এরি হারমান

উত্তর:


18

ভূমিকা

আমি এই প্রশ্নটি সত্যিই আকর্ষণীয় মনে করি, আমি ধরেই নিয়েছি যে কেউ এটির উপর একটি কাগজ ফেলেছে তবে এটি আমার দিন অবসান, তাই আমি রেফারেন্সগুলি তাড়া করতে যেতে চাই না।

সুতরাং আমরা এটিকে আউটপুটটির প্রতিনিধিত্ব / এনকোডিং হিসাবে বিবেচনা করতে পারি, যা আমি এই উত্তরে করি। আমি ভাবছি যে আরও ভাল উপায় আছে যেখানে আপনি কিছুটা আলাদা লোকসান ফাংশন ব্যবহার করতে পারেন। (সম্ভবত বিয়োগফল 2 ব্যবহার করে বর্গক্ষেত্রের পার্থক্যের যোগফল )।π

তবে আসল উত্তর দিয়েই পরে।

পদ্ধতি

আমি প্রস্তাব দিচ্ছি যে একটি কোণ মান, এর সাইন এবং এর কোসাইন হিসাবে এক জোড়া হিসাবে উপস্থাপন করা হবে।θ

সুতরাং এনকোডিং ফাংশনটি হ'ল: এবং ডিকোডিং ফাংশনটি হ'ল: জন্য arctan2 বিপরীত tangents হচ্ছে, সব অর্ধেই দিক নির্দেশনা সংরক্ষণের)θ(sin(θ),cos(θ))
(y1,y2)arctan2(y1,y2)

আপনি যদি তাত্ত্বিকভাবে সমানভাবে কোণগুলির সাথে সরাসরি কাজ করতে পারেন তবে যদি আপনার সরঞ্জামটি atan2কোনও স্তর ফাংশন হিসাবে সমর্থন করে (ঠিক 2 ইনপুট গ্রহণ করে এবং 1 আউটপুট উত্পাদন করে)। টেনসরফ্লো এখন এটি করে এবং এটিতে গ্রেডিয়েন্ট বংশোদ্ভূতিকে সমর্থন করে যদিও এটি এই ব্যবহারের উদ্দেশ্যে নয়। আমি out = atan2(sigmoid(ylogit), sigmoid(xlogit)) একটি ক্ষতি ফাংশন ব্যবহার করে তদন্ত করেছি min((pred - out)^2, (pred - out - 2pi)^2)। আমি দেখতে পেয়েছি যে এটি outs = tanh(ylogit), outc = tanh(xlogit)) কোনও ক্ষতির ফাংশন ব্যবহারের চেয়ে আরও খারাপ প্রশিক্ষিত হয়েছে 0.5((sin(pred) - outs)^2 + (cos(pred) - outc)^2। যা আমি মনে করি এর জন্য গ্রেডিয়েন্টটি বিচ্ছিন্ন হওয়ার জন্য দায়ী করা যেতে পারেatan2

আমার টেস্টিং এখানে এটি প্রাকপ্রসেসিং ফাংশন হিসাবে চালিত করে

এটি মূল্যায়নের জন্য আমি একটি কার্য সংজ্ঞায়িত করেছি:

একটি ফাঁকা পটভূমিতে একটি একক লাইন উপস্থাপন করে এমন একটি কালো এবং সাদা চিত্র দেওয়া যা সেই লাইনটি "ধনাত্মক এক্স-অক্ষ" এর সাথে কোন কোণে আউটপুট দেয়

আমি এলোমেলোভাবে এ চিত্রগুলি উত্পন্ন করার জন্য একটি ক্রিয়াকলাপ বাস্তবায়িত করেছি, এলোমেলো কোণগুলিতে রেখার সাথে (এনবি: এই পোস্টের পূর্ববর্তী সংস্করণগুলি এলোমেলো কোণগুলির চেয়ে এলোমেলো slালু ব্যবহার করেছে point আমি কার্যটির কার্যকারিতা মূল্যায়নের জন্য বেশ কয়েকটি নিউরাল নেটওয়ার্ক তৈরি করেছি। বাস্তবায়নের পুরো বিশদটি এই বৃহত্তর নোটবুকে রয়েছে । কোডটি সমস্ত জুলিয়ায় এবং আমি মোচা নিউরাল নেটওয়ার্ক লাইব্রেরিটি ব্যবহার করি ।

তুলনার জন্য, আমি এটি স্কেলিংয়ের বিকল্প পদ্ধতির বিরুদ্ধে 0,1 তে উপস্থাপন করছি। এবং 500 টি বিনগুলিতে স্থাপন এবং সফট-লেবেল সফটম্যাক্স ব্যবহার করতে। আমি শেষের সাথে বিশেষভাবে সন্তুষ্ট নই এবং আমার এটির টুইট করার দরকার আছে বলে মনে হয়। এ কারণেই, অন্যদের মতো আমি এটি কেবল 1,000 পুনরাবৃত্তির জন্য পরীক্ষা করে দেখি, অন্য দুটি তুলনায় যা 1000 এবং 10,000 এর জন্য চালানো হয়েছিল

পরীক্ষামূলক সেটআপ

চিত্রগুলি পিক্সেল ছিল, রেখাটি কেন্দ্রের সাথে শুরু হয়ে প্রান্তে চলেছে। ছবিটিতে কোনও গোলমাল ইত্যাদি ছিল না, একটি সাদা পটভূমিতে কেবল একটি "কালো" রেখা।101×101

প্রতিটি ট্রেইলের জন্য 1,000 প্রশিক্ষণ এবং 1,000 পরীক্ষাগুলি এলোমেলোভাবে তৈরি করা হয়েছিল।

মূল্যায়ন নেটওয়ার্কের 500 প্রস্থের একক লুকানো স্তর ছিল the সিগময়েড নিউরনগুলি লুকানো স্তরে ব্যবহৃত হত।

এটি স্টোকাস্টিক গ্রেডিয়েন্ট ডেসেন্ট দ্বারা প্রশিক্ষিত হয়েছিল, 0.01 এর একটি নির্দিষ্ট শিক্ষার হার এবং 0.9 এর একটি নির্দিষ্ট গতিবেগ সহ।

কোনও নিয়ন্ত্রণ বা ড্রপআউট ব্যবহার করা হয়নি। এমনকি কোনও ধরণের সমঝোতা ইত্যাদি ছিল না একটি সহজ নেটওয়ার্ক, যা আমি আশা করি যে এই ফলাফলগুলি সাধারণীকরণ করবে

পরীক্ষার কোডে এই পরামিতিগুলি টুইট করা খুব সহজ , এবং আমি লোকদের তা করতে উত্সাহিত করি। (এবং পরীক্ষায় বাগগুলি সন্ধান করুন)।

ফলাফল

আমার ফলাফলগুলি নিম্নরূপ:

|                        |  500 bins    |  scaled to 0-1 |  Sin/Cos     |  scaled to 0-1 |  Sin/Cos     |
|                        | 1,000 Iter   | 1,000 Iter     | 1,000 iter   | 10,000 Iter    | 10,000 iter  |
|------------------------|--------------|----------------|--------------|----------------|--------------|
| mean_error             | 0.4711263342 | 0.2225284486   | 2.099914718  | 0.1085846429   | 2.1036656318 |
| std(errors)            | 1.1881991421 | 0.4878383767   | 1.485967909  | 0.2807570442   | 1.4891605068 |
| minimum(errors)        | 1.83E-006    | 1.82E-005      | 9.66E-007    | 1.92E-006      | 5.82E-006    |
| median(errors)         | 0.0512168533 | 0.1291033982   | 1.8440767072 | 0.0562908143   | 1.8491085947 |
| maximum(errors)        | 6.0749693965 | 4.9283551248   | 6.2593307366 | 3.735884823    | 6.2704853962 |
| accurancy              | 0.00%        | 0.00%          | 0.00%        | 0.00%          | 0.00%        |
| accurancy_to_point001  | 2.10%        | 0.30%          | 3.70%        | 0.80%          | 12.80%       |
| accurancy_to_point01   | 21.90%       | 4.20%          | 37.10%       | 8.20%          | 74.60%       |
| accurancy_to_point1    | 59.60%       | 35.90%         | 98.90%       | 72.50%         | 99.90%       |

যেখানে আমি ত্রুটির কথা উল্লেখ করি, এটি নিউরাল নেটওয়ার্ক দ্বারা কোণ আউটপুট এবং সত্য কোণের পার্থক্যের পরম মানের the সুতরাং গড় ত্রুটি (উদাহরণস্বরূপ) এই পার্থক্যের 1000 টিরও বেশি পরীক্ষার গড়ের গড় etc. equal সমান বলে ভুল করে আমি এটিকে পুনরুদ্ধার করব না তা নিশ্চিত নই I ) এর ত্রুটিতে । π7π4π4

আমি বিভিন্ন স্তরের গ্র্যানুলারিটিতেও যথার্থতা উপস্থাপন করি। যথার্থতা পরীক্ষার কেসগুলির অংশ হওয়ায় এটি প্রমাণিত হয়েছে। সুতরাং accuracy_to_point01আউটপুটটি সত্য কোণের 0.01 এর মধ্যে থাকলে এটি সঠিক হিসাবে গণ্য হয়েছিল। উপস্থাপনগুলির কোনওরই কোনও নিখুঁত ফলাফল পাওয়া যায়নি, তবে এটি ভাসমান পয়েন্ট গণিত কীভাবে কাজ করে তা অবাক করে কিছু নয়।

আপনি যদি এই পোস্টের ইতিহাসটি একবার দেখে থাকেন তবে আপনি দেখতে পাবেন যে ফলাফলগুলি তাদের কাছে কিছুটা আওয়াজ পেয়েছে, প্রতিবার এটি পুনরায় চালু করার সময় কিছুটা আলাদা different তবে মানগুলির সাধারণ ক্রম এবং স্কেল একই থাকে; এইভাবে আমাদের কিছু সিদ্ধান্তে টানতে দেয়।

আলোচনা

সফটম্যাক্সের সাথে বিনিং সবচেয়ে খারাপভাবে সম্পাদন করে, কারণ আমি বলেছিলাম যে আমি বাস্তবায়নে কোনও কিছু স্ক্রু করিনি তা নিশ্চিত নই। এটি অনুমানের হারের তুলনায় কিছুটা কম পারফরম্যান্স করে। যদি এটি কেবল অনুমান করা হত তবে আমরা এর একটি ভুল ত্রুটি পেয়ে যাচ্ছিπ

পাপ / কোস এনকোডিংটি স্কেলড 0-1 এনকোডিংয়ের চেয়ে উল্লেখযোগ্যভাবে ভাল সম্পাদন করে। উন্নতি হ'ল 10,000 প্রশিক্ষণের পুনরাবৃত্তিতে পাপ / কোস বেশিরভাগ মেট্রিকের তুলনায় প্রায় 3 গুণ ভাল সম্পাদন করছে যা স্কেলিং 10,000 এর পুনরাবৃত্তিতে হয়।

আমি মনে করি, অংশটি এটি সাধারণীকরণের উন্নতির সাথে সম্পর্কিত, কারণ উভয়ই প্রশিক্ষণের সেটটিতে মোটামুটি একইভাবে গড় স্কোয়ার ত্রুটি পেয়েছিল, অন্তত একবার 10,000 পুনরাবৃত্তি চালানো হয়েছিল।

এই কার্যক্রমে সেরা সম্ভাব্য পারফরম্যান্সের অবশ্যই একটি উচ্চতর সীমা রয়েছে, প্রদত্ত অ্যাঙ্গেল কম-বেশি যে কোনও আসল সংখ্যা হতে পারে তবে এই জাতীয় সমস্ত ফেরেশতা পিক্সেলের রেজোলিউশনে বিভিন্ন লাইন তৈরি করে না । সুতরাং, উদাহরণস্বরূপ, ৪৫.০ এবং 45.0000001 উভয় কোণই সেই রেজোলিউশনে একই চিত্রের সাথে আবদ্ধ, কোনও পদ্ধতিই উভয়ই পুরোপুরি সঠিক হবে না।101×101

এটি সম্ভবত মনে হয় যে এই পারফরম্যান্সের বাইরে যাওয়ার জন্য নিরঙ্কুশ স্কেলে আরও ভাল নিউরাল নেটওয়ার্কের প্রয়োজন। পরীক্ষামূলক সেটআপে উপরে উল্লিখিত খুব সাধারণ একটির চেয়ে।

উপসংহার।

মনে হয় যে পাপ / কোসের উপস্থাপনা আমি এখানে উপস্থাপন করেছি তার মধ্যে সবচেয়ে ভাল। এটি বৃত্তির চারপাশে ঘোরাঘুরি করার সাথে সাথে এটির মসৃণ মান হয় না এর অর্থ হয়। আমি এটিও পছন্দ করি যে বিপরীতটি আর্টিকান 2 দিয়ে করা যায় যা মার্জিত।

আমি বিশ্বাস করি যে উপস্থাপিত কাজটি নেটওয়ার্কের জন্য একটি যুক্তিসঙ্গত চ্যালেঞ্জ উপস্থাপনের দক্ষতার পক্ষে যথেষ্ট। যদিও আমি অনুমান করি সত্যই এটি কার্ভ ফিটিং করা শিখছে তাই সম্ভবত এটি খুব সহজ। এবং সম্ভবত আরও খারাপ এটি জোড় উপস্থাপনের পক্ষে হতে পারে। আমি মনে করি না এটি হ'ল, তবে এখানে দেরি হচ্ছে, তাই আমি আমার কোডটি সন্ধানের জন্য আপনাকে আবার আমন্ত্রণ জানিয়েছিলাম এমন কিছু মিস করেছি । উন্নতি বা বিকল্প কাজের পরামর্শ দিন।f(x)=y1y2x


এটি অবশ্যই স্ট্যাক এক্সচেঞ্জের সময়ে আমি সবচেয়ে সুনির্দিষ্ট প্রতিক্রিয়া পেয়েছি। যেহেতু আমি জুলিয়ার সাথে পরিচিত নই, তাই আপনার কোড পরীক্ষা করা আমার পক্ষে কঠিন ... তাই পরিবর্তে আমি পাইথন ব্যবহার করে আপনার ফলাফলগুলি প্রতিলিপি দেওয়ার চেষ্টা করতে যাচ্ছি। আমি আজ বা কাল আমাকে অনুসন্ধান পোস্ট করব
এরি হারমান

বিনিংটি খারাপভাবে অভিনয় করায় আমি অবাক হইনি, আমি (ডিগ্রি পাপ) পদ্ধতিতে (0,1) স্কেলিং যে পরিমাণে ছাড়িয়ে গেছে তাতে আমি অবাক হয়েছি। আমি লক্ষ্য করেছি যে আপনি এলোমেলোভাবে রেখাগুলির উত্থান এবং রান বাছাই করে আপনার উদাহরণগুলি তৈরি করেছেন। এটি আমার মনে হয়, এমন লাইনগুলি তৈরি করবে যার কোণগুলি সমানভাবে বিতরণ করা হয়নি, তবে যার opালু। এটা কি সম্ভব যে এ কারণেই (কোস, পাপ) পদ্ধতিটি আরও ভালভাবে সম্পাদিত হয়েছিল? আপনি যদি লক্ষ্যগুলি ট্যান (কোণ) তৈরি করেন তবে কী হবে ...?
এরি হারমান

আপনি এলোমেলো vsাল বনাম এলোমেলো কোণ সম্পর্কে ঠিক। তবে আমি মনে করি না লক্ষ্যগুলি tan(angle)এত ভালভাবে চলে যাবে, ট্যানের চেয়ে বেশি দেওয়া সমস্ত কোণে সংজ্ঞায়িত করা হয়নি (যেমন )। আমি এলোমেলোভাবে উত্পন্ন কোণগুলির সাথে এটি পুনরায় চালু করব এবং পোস্টগুলি সম্পাদনা করব। π/4
লিন্ডন হোয়াইট

জুলিয়া এবং নিম্পির মধ্যে এবং মোচা এবং ক্যাফের মধ্যে এক থেকে এক মানচিত্রের খুব কাছাকাছি হওয়া উচিত, যদি আপনি সত্যিই এটি পুনরায় প্রয়োগ করতে চান। আপনি যে কোডটি পড়তে কষ্ট পেয়েছেন তার কোনও নির্দিষ্ট অংশ আছে? জুলিয়া ভাষা বুঝতে সহজ হওয়া উচিত। তাই সম্ভবত আমি কিছু অদ্ভুত কাজ করেছি।
লিন্ডন হোয়াইট

আমি আপনার কোড পড়া শেষ করেছি, এবং সবকিছু সঠিক বলে মনে হচ্ছে। তবুও, আমি নিজের সংস্করণটি লিখতে চেয়েছিলাম, যেহেতু এটি করা সাধারণত শিক্ষণীয়। আমার বাস্তবায়ন আপনার থেকে কিছুটা আলাদা, সুতরাং ফলাফলের তুলনা করা আকর্ষণীয় হবে। আমি কয়েক ঘন্টা পরে তাদের পোস্ট করা হবে।
এরি হারমান

5

লিন্ডন হোয়াইটের প্রস্তাবিত এনকোডিংটিকে একটি বিনাশিত পদ্ধতির সাথে তুলনা করার জন্য এখানে পাইথনের আরও একটি বাস্তবায়ন রয়েছে । নীচের কোডটি নিম্নলিখিত আউটপুট উত্পাদন করেছে:

Training Size: 100
Training Epochs: 100
Encoding: cos_sin
Test Error: 0.017772154610047136
Encoding: binned
Test Error: 0.043398792553251526

Training Size: 100
Training Epochs: 500
Encoding: cos_sin
Test Error: 0.015376604917819397
Encoding: binned
Test Error: 0.032942592915322394

Training Size: 1000
Training Epochs: 100
Encoding: cos_sin
Test Error: 0.007544091937411164
Encoding: binned
Test Error: 0.012796594492198667

Training Size: 1000
Training Epochs: 500
Encoding: cos_sin
Test Error: 0.0038051515079569097
Encoding: binned
Test Error: 0.006180633805557207

(sin(θ),cos(θ))(sin(θ),cos(θ))

import matplotlib.pyplot as plt
import numpy as np
import torch
import torch.nn as nn
import torch.utils.data

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")


class Net(nn.Module):
    def __init__(self, input_size, hidden_size, num_out):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(input_size, hidden_size)
        self.sigmoid = nn.Sigmoid()
        self.fc2 = nn.Linear(hidden_size, num_out)

    def forward(self, x):
        out = self.fc1(x)
        out = self.sigmoid(out)
        out = self.fc2(out)
        return out


def gen_train_image(angle, side, thickness):
    image = np.zeros((side, side))
    (x_0, y_0) = (side / 2, side / 2)
    (c, s) = (np.cos(angle), np.sin(angle))
    for y in range(side):
        for x in range(side):
            if (abs((x - x_0) * c + (y - y_0) * s) < thickness / 2) and (
                    -(x - x_0) * s + (y - y_0) * c > 0):
                image[x, y] = 1

    return image.flatten()


def gen_data(num_samples, side, num_bins, thickness):
    angles = 2 * np.pi * np.random.uniform(size=num_samples)
    X = [gen_train_image(angle, side, thickness) for angle in angles]
    X = np.stack(X)

    y = {"cos_sin": [], "binned": []}
    bin_size = 2 * np.pi / num_bins
    for angle in angles:
        idx = int(angle / bin_size)
        y["binned"].append(idx)
        y["cos_sin"].append(np.array([np.cos(angle), np.sin(angle)]))

    for enc in y:
        y[enc] = np.stack(y[enc])

    return (X, y, angles)


def get_model_stuff(train_y, input_size, hidden_size, output_sizes,
                    learning_rate, momentum):
    nets = {}
    optimizers = {}

    for enc in train_y:
        net = Net(input_size, hidden_size, output_sizes[enc])
        nets[enc] = net.to(device)
        optimizers[enc] = torch.optim.SGD(net.parameters(), lr=learning_rate,
                                          momentum=momentum)

    criterions = {"binned": nn.CrossEntropyLoss(), "cos_sin": nn.MSELoss()}
    return (nets, optimizers, criterions)


def get_train_loaders(train_X, train_y, batch_size):
    train_X_tensor = torch.Tensor(train_X)

    train_loaders = {}

    for enc in train_y:
        if enc == "binned":
            train_y_tensor = torch.tensor(train_y[enc], dtype=torch.long)
        else:
            train_y_tensor = torch.tensor(train_y[enc], dtype=torch.float)

        dataset = torch.utils.data.TensorDataset(train_X_tensor, train_y_tensor)
        train_loader = torch.utils.data.DataLoader(dataset=dataset,
                                                   batch_size=batch_size,
                                                   shuffle=True)
        train_loaders[enc] = train_loader

    return train_loaders


def show_image(image, side):
    img = plt.imshow(np.reshape(image, (side, side)), interpolation="nearest",
                     cmap="Greys")
    plt.show()


def main():
    side = 101
    input_size = side ** 2
    thickness = 5.0
    hidden_size = 500
    learning_rate = 0.01
    momentum = 0.9
    num_bins = 500
    bin_size = 2 * np.pi / num_bins
    half_bin_size = bin_size / 2
    batch_size = 50
    output_sizes = {"binned": num_bins, "cos_sin": 2}
    num_test = 1000

    (test_X, test_y, test_angles) = gen_data(num_test, side, num_bins,
                                             thickness)

    for num_train in [100, 1000]:

        (train_X, train_y, train_angles) = gen_data(num_train, side, num_bins,
                                                    thickness)
        train_loaders = get_train_loaders(train_X, train_y, batch_size)

        for epochs in [100, 500]:

            (nets, optimizers, criterions) = get_model_stuff(train_y, input_size,
                                                             hidden_size, output_sizes,
                                                             learning_rate, momentum)

            for enc in train_y:
                optimizer = optimizers[enc]
                net = nets[enc]
                criterion = criterions[enc]

                for epoch in range(epochs):
                    for (i, (images, ys)) in enumerate(train_loaders[enc]):
                        optimizer.zero_grad()

                        outputs = net(images.to(device))
                        loss = criterion(outputs, ys.to(device))
                        loss.backward()
                        optimizer.step()


            print("Training Size: {0}".format(num_train))
            print("Training Epochs: {0}".format(epochs))
            for enc in train_y:
                net = nets[enc]
                preds = net(torch.tensor(test_X, dtype=torch.float).to(device))
                if enc == "binned":
                    pred_bins = np.array(preds.argmax(dim=1).detach().cpu().numpy(),
                                         dtype=np.float)
                    pred_angles = bin_size * pred_bins + half_bin_size
                else:
                    pred_angles = torch.atan2(preds[:, 1], preds[:, 0]).detach().cpu().numpy()
                    pred_angles[pred_angles < 0] = pred_angles[pred_angles < 0] + 2 * np.pi

                print("Encoding: {0}".format(enc))
                print("Test Error: {0}".format(np.abs(pred_angles - test_angles).mean()))

            print()


if __name__ == "__main__":
    main()

3

আপনার পরীক্ষার আমার পাইথন সংস্করণটি এখানে। আমি আপনার প্রয়োগের অনেকগুলি বিবরণ একই রেখেছি, বিশেষত আমি একই চিত্রের আকার, নেটওয়ার্ক স্তর আকার, শেখার হার, গতি এবং সাফল্যের মেট্রিক্স ব্যবহার করি।

প্রতিটি নেটওয়ার্কের পরীক্ষিত লজিস্টিক নিউরনের সাথে একটি লুকানো স্তর (আকার = 500) থাকে। উল্লিখিত হিসাবে আউটপুট নিউরনগুলি লিনিয়ার বা সফটম্যাক্স হয়। আমি 1,000 প্রশিক্ষণ চিত্র এবং 1,000 পরীক্ষা চিত্র ব্যবহার করেছি যা স্বতন্ত্রভাবে, এলোমেলোভাবে উত্পন্ন হয়েছিল (যাতে পুনরাবৃত্তি হতে পারে)। প্রশিক্ষণ প্রশিক্ষণের মাধ্যমে 50 পুনরাবৃত্তি নিয়ে গঠিত।

আমি বিনিং এবং "গাউসিয়ান" এনকোডিং ব্যবহার করে বেশ ভাল নির্ভুলতা অর্জন করতে সক্ষম হয়েছি (টার্গেট আউটপুট ভেক্টরটির ফর্ম এক্সপ্রেস (-পিআই * ([1,2,3, ... ... , 500] - আইডিএক্স) ** 2) যেখানে আইডিএক্স হ'ল সঠিক কোণের সাথে সম্পর্কিত সূচক)। কোডটি নীচে রয়েছে; এখানে আমার ফলাফল:

(কোস, পাপ) এনকোডিংয়ের জন্য পরীক্ষার ত্রুটি:

1,000 প্রশিক্ষণ চিত্র, 1,000 পরীক্ষার চিত্র, 50 পুনরাবৃত্তি, রৈখিক আউটপুট

  • গড়: 0.0911558142071

  • মিডিয়ান: 0.0429723541743

  • সর্বনিম্ন: 2.77769843793e-06

  • সর্বাধিক: 6.2608513539

  • যথার্থতা 0.1: 85.2%

  • নির্ভুলতা 0.01: 11.6%

  • যথার্থতা 0.001: 1.0%

[-1,1] এনকোডিংয়ের জন্য পরীক্ষার ত্রুটি:

1,000 প্রশিক্ষণ চিত্র, 1,000 পরীক্ষার চিত্র, 50 পুনরাবৃত্তি, রৈখিক আউটপুট

  • গড়: 0.234181700523

  • মিডিয়ান: 0.17460197307

  • সর্বনিম্ন: 0.000473665840258

  • সর্বাধিক: 6.00637777237

  • যথার্থতা 0.1: 29.9%

  • নির্ভুলতা 0.01: 3.3%

  • যথার্থতা 0.001: 0.1%

500 এর 1-এর এনকোডিংয়ের জন্য পরীক্ষার ত্রুটি:

1,000 প্রশিক্ষণ চিত্র, 1,000 পরীক্ষার চিত্র, 50 পুনরাবৃত্তি, সফটম্যাক্স আউটপুট

  • গড়: 0.0298767021922

  • মিডিয়ান: 0.00388858079174

  • সর্বনিম্ন: 4.08712407829e-06

  • সর্বাধিক: 6.2784479965

  • যথার্থতা 0.1: 99.6%

  • নির্ভুলতা 0.01: 88.9%

  • যথার্থতা 0.001: 13.5%

গাউসিয়ান এনকোডিংয়ের জন্য পরীক্ষার ত্রুটি:

1,000 প্রশিক্ষণ চিত্র, 1,000 পরীক্ষার চিত্র, 50 পুনরাবৃত্তি, সফটম্যাক্স আউটপুট

  • গড়: 0.0296905377463
  • মিডিয়ান: 0.00365867335107
  • সর্বনিম্ন: 4.08712407829e-06
  • সর্বাধিক: 6.2784479965
  • যথার্থতা 0.1: 99.6%
  • নির্ভুলতা 0.01: 90.8%
  • যথার্থতা 0.001: 14.3%

কেন আমাদের ফলাফলগুলি একে অপরের সাথে বিরোধী বলে মনে হচ্ছে তা বুঝতে পারি না, তবে এটি আরও তদন্ত করার মতো বলে মনে হচ্ছে।

# -*- coding: utf-8 -*-
"""
Created on Mon Jun 13 16:59:53 2016

@author: Ari
"""

from numpy import savetxt, loadtxt, round, zeros, sin, cos, arctan2, clip, pi, tanh, exp, arange, dot, outer, array, shape, zeros_like, reshape, mean, median, max, min
from numpy.random import rand, shuffle
import matplotlib.pyplot as plt

###########
# Functions
###########

# Returns a B&W image of a line represented as a binary vector of length width*height
def gen_train_image(angle, width, height, thickness):
    image = zeros((height,width))
    x_0,y_0 = width/2, height/2
    c,s = cos(angle),sin(angle)
    for y in range(height):
        for x in range(width):
            if abs((x-x_0)*c + (y-y_0)*s) < thickness/2 and -(x-x_0)*s + (y-y_0)*c > 0:
                image[x,y] = 1
    return image.flatten()

# Display training image    
def display_image(image,height, width):    
    img = plt.imshow(reshape(image,(height,width)), interpolation = 'nearest', cmap = "Greys")
    plt.show()    

# Activation function
def sigmoid(X):
    return 1.0/(1+exp(-clip(X,-50,100)))

# Returns encoded angle using specified method ("binned","scaled","cossin","gaussian")
def encode_angle(angle, method):
    if method == "binned": # 1-of-500 encoding
        X = zeros(500)
        X[int(round(250*(angle/pi + 1)))%500] = 1
    elif method == "gaussian": # Leaky binned encoding
        X = array([i for i in range(500)])
        idx = 250*(angle/pi + 1)
        X = exp(-pi*(X-idx)**2)
    elif method == "scaled": # Scaled to [-1,1] encoding
        X = array([angle/pi])
    elif method == "cossin": # Oxinabox's (cos,sin) encoding
        X = array([cos(angle),sin(angle)])
    else:
        pass
    return X

# Returns decoded angle using specified method
def decode_angle(X, method):
    if method == "binned" or method == "gaussian": # 1-of-500 or gaussian encoding
        M = max(X)
        for i in range(len(X)):
            if abs(X[i]-M) < 1e-5:
                angle = pi*i/250 - pi
                break
#        angle = pi*dot(array([i for i in range(500)]),X)/500  # Averaging
    elif method == "scaled": # Scaled to [-1,1] encoding
        angle = pi*X[0]
    elif method == "cossin": # Oxinabox's (cos,sin) encoding
        angle = arctan2(X[1],X[0])
    else:
        pass
    return angle

# Train and test neural network with specified angle encoding method
def test_encoding_method(train_images,train_angles,test_images, test_angles, method, num_iters, alpha = 0.01, alpha_bias = 0.0001, momentum = 0.9, hid_layer_size = 500):
    num_train,in_layer_size = shape(train_images)
    num_test = len(test_angles)

    if method == "binned":
        out_layer_size = 500
    elif method == "gaussian":
        out_layer_size = 500
    elif method == "scaled":
        out_layer_size = 1
    elif method == "cossin":
        out_layer_size = 2
    else:
        pass

    # Initial weights and biases
    IN_HID = rand(in_layer_size,hid_layer_size) - 0.5 # IN --> HID weights
    HID_OUT = rand(hid_layer_size,out_layer_size) - 0.5 # HID --> OUT weights
    BIAS1 = rand(hid_layer_size) - 0.5 # Bias for hidden layer
    BIAS2 = rand(out_layer_size) - 0.5 # Bias for output layer

    # Initial weight and bias updates
    IN_HID_del = zeros_like(IN_HID)
    HID_OUT_del = zeros_like(HID_OUT)
    BIAS1_del = zeros_like(BIAS1)
    BIAS2_del = zeros_like(BIAS2)

    # Train
    for j in range(num_iters):
        for i in range(num_train):
            # Get training example
            IN = train_images[i]
            TARGET = encode_angle(train_angles[i],method) 

            # Feed forward and compute error derivatives
            HID = sigmoid(dot(IN,IN_HID)+BIAS1)

            if method == "binned" or method == "gaussian": # Use softmax
                OUT = exp(clip(dot(HID,HID_OUT)+BIAS2,-100,100))
                OUT = OUT/sum(OUT)
                dACT2 = OUT - TARGET
            elif method == "cossin" or method == "scaled": # Linear
                OUT = dot(HID,HID_OUT)+BIAS2 
                dACT2 = OUT-TARGET 
            else:
                print("Invalid encoding method")

            dHID_OUT = outer(HID,dACT2)
            dACT1 = dot(dACT2,HID_OUT.T)*HID*(1-HID)
            dIN_HID = outer(IN,dACT1)
            dBIAS1 = dACT1
            dBIAS2 = dACT2

            # Update the weight updates 
            IN_HID_del = momentum*IN_HID_del + (1-momentum)*dIN_HID
            HID_OUT_del = momentum*HID_OUT_del + (1-momentum)*dHID_OUT
            BIAS1_del = momentum*BIAS1_del + (1-momentum)*dBIAS1
            BIAS2_del = momentum*BIAS2_del + (1-momentum)*dBIAS2

            # Update the weights
            HID_OUT -= alpha*dHID_OUT
            IN_HID -= alpha*dIN_HID
            BIAS1 -= alpha_bias*dBIAS1
            BIAS2 -= alpha_bias*dBIAS2

    # Test
    test_errors = zeros(num_test)
    angles = zeros(num_test)
    target_angles = zeros(num_test)
    accuracy_to_point001 = 0
    accuracy_to_point01 = 0
    accuracy_to_point1 = 0

    for i in range(num_test):

        # Get training example
        IN = test_images[i]
        target_angle = test_angles[i]

        # Feed forward
        HID = sigmoid(dot(IN,IN_HID)+BIAS1)

        if method == "binned" or method == "gaussian":
            OUT = exp(clip(dot(HID,HID_OUT)+BIAS2,-100,100))
            OUT = OUT/sum(OUT)
        elif method == "cossin" or method == "scaled":
            OUT = dot(HID,HID_OUT)+BIAS2 

        # Decode output 
        angle = decode_angle(OUT,method)

        # Compute errors
        error = abs(angle-target_angle)
        test_errors[i] = error
        angles[i] = angle

        target_angles[i] = target_angle
        if error < 0.1:
            accuracy_to_point1 += 1
        if error < 0.01: 
            accuracy_to_point01 += 1
        if error < 0.001:
            accuracy_to_point001 += 1

    # Compute and return results
    accuracy_to_point1 = 100.0*accuracy_to_point1/num_test
    accuracy_to_point01 = 100.0*accuracy_to_point01/num_test
    accuracy_to_point001 = 100.0*accuracy_to_point001/num_test

    return mean(test_errors),median(test_errors),min(test_errors),max(test_errors),accuracy_to_point1,accuracy_to_point01,accuracy_to_point001

# Dispaly results
def display_results(results,method):
    MEAN,MEDIAN,MIN,MAX,ACC1,ACC01,ACC001 = results
    if method == "binned":
        print("Test error for 1-of-500 encoding:")
    elif method == "gaussian":
        print("Test error for gaussian encoding: ")
    elif method == "scaled":
        print("Test error for [-1,1] encoding:")
    elif method == "cossin":
        print("Test error for (cos,sin) encoding:")
    else:
        pass
    print("-----------")
    print("Mean: "+str(MEAN))
    print("Median: "+str(MEDIAN))
    print("Minimum: "+str(MIN))
    print("Maximum: "+str(MAX))
    print("Accuracy to 0.1: "+str(ACC1)+"%")
    print("Accuracy to 0.01: "+str(ACC01)+"%")
    print("Accuracy to 0.001: "+str(ACC001)+"%")
    print("\n\n")


##################
# Image parameters
##################
width = 100 # Image width
height = 100 # Image heigth
thickness = 5.0 # Line thickness

#################################
# Generate training and test data
#################################
num_train = 1000
num_test = 1000
test_images = []
test_angles = []
train_images = []
train_angles = []
for i in range(num_train):
    angle = pi*(2*rand() - 1)
    train_angles.append(angle)
    image = gen_train_image(angle,width,height,thickness)
    train_images.append(image)
for i in range(num_test):
    angle = pi*(2*rand() - 1)
    test_angles.append(angle)
    image = gen_train_image(angle,width,height,thickness)
    test_images.append(image)
train_angles,train_images,test_angles,test_images = array(train_angles),array(train_images),array(test_angles),array(test_images)



###########################
# Evaluate encoding schemes
###########################
num_iters = 50

# Train with cos,sin encoding
method = "cossin"
results1 = test_encoding_method(train_images, train_angles, test_images, test_angles, method, num_iters)
display_results(results1,method)

# Train with scaled encoding
method = "scaled"
results3 = test_encoding_method(train_images, train_angles, test_images, test_angles, method, num_iters)
display_results(results3,method)

# Train with binned encoding
method = "binned"
results2 = test_encoding_method(train_images, train_angles, test_images, test_angles, method, num_iters)
display_results(results2,method)

# Train with gaussian encoding
method = "gaussian"
results4 = test_encoding_method(train_images, train_angles, test_images, test_angles, method, num_iters)
display_results(results4,method)

দুর্দান্ত, অন কী আলাদা। আপনি কেবল একবারে প্রতিটি চিত্রের উপর প্রশিক্ষণ নিচ্ছেন। আমি প্রতিটি চিত্রের উপর 1,000 বার বা 10,000 বার প্রশিক্ষণ দিচ্ছি। একাধিক আইট্রেশন যদিও প্রশিক্ষণের ডেটা স্বাভাবিক থাকে, বিশেষত তুলনামূলকভাবে খুব অল্প পরিমাণে ডেটা সম্পর্কে প্রশিক্ষণ দেওয়া হলে (এবং এটি শিখতে আমাকে কেবল একটি অপ্রকাশিত আন্ডারগ্রাড থিসিস নিয়েছিল, তবে এটি অন্য গল্প) is এই বলেছিলাম, আমার টেবিলে আমার 1 টি কলাম কলাম যুক্ত করা উচিত। তথ্যবহুল হবে
লিন্ডন হোয়াইট

আমি ভাবব যে অনুরূপ লক্ষ্যযুক্ত সমান (তবে অভিন্ন নয়) চিত্রগুলির উপর প্রশিক্ষণ সেই নেটওয়ার্কটিকে একইভাবে প্রভাবিত করবে। যদি এটি সত্য হয় তবে ছোট প্রশিক্ষণ সংস্থার মাধ্যমে বহুবার পুনরাবৃত্তি না করে প্রশিক্ষণ দেওয়া এলোমেলো চিত্রগুলির সংখ্যা বাড়িয়ে তুলতে কাজ করা উচিত। আপনি কি বলছেন যে এটি না?
এরি হারমান

এটি একই রকম, তবে উদাহরণস্বরূপ কার্যটির ক্ষেত্রে এটির সমস্যা নেই যা শেষ পর্যন্ত আপনি সমস্ত সম্ভাব্য চিত্র দেখিয়ে দেবেন যাতে আপনার পরীক্ষাটি আপনার ট্রেনের সাথে ওভারল্যাপ হয়ে যায়, তাই সাধারণীকরণ পরীক্ষা করা কার্যকর হবে না। আরও লক্ষণীয়ভাবে আপনি 100,000 প্রশিক্ষণ চিত্রগুলি করেন তবে এটি <1000 * 1000 প্রশিক্ষণ চিত্রগুলি * আইট্রেটিস।
লিন্ডন হোয়াইট

আপনি সঠিক, আমি এই সমস্যাটি ঠিক করব। আমার কোডটির সাথে আরও তাত্পর্যপূর্ণ সমস্যা রয়েছে: আমি লজিস্টিক নিউরনগুলি ব্যবহার করছি যা (কোস, পাপ) উপস্থাপনের জন্য প্রয়োজনীয় নেতিবাচক মান উত্পাদন করতে অক্ষম। ডি আহা! আমি আমার কোডটি সংশোধন করব এবং যত তাড়াতাড়ি সম্ভব পুনরায় পোস্ট করব।
এরি হারমান

আপনি (যদি আপনি ইতিমধ্যে এটি না করে থাকেন) গ্র্যাজেন্ট চেক করতে আগ্রহী হতে পারেন , যা স্ক্র্যাচ থেকে নিউরাল নেটওয়ার্কগুলি প্রয়োগ করার সময় সার্থক কারণ একটি ছোটখাটো ভুল করা খুব সহজ এবং আপনার নেটওয়ার্কটি এখনও বেশিরভাগ ক্ষেত্রেই কাজ করে। পুন: নিউরন: হ্যাঁ, সিগময়েড লুকানো স্তরটির উপরে আমার একটি লিনিয়ার আউটপুট স্তর রয়েছে
লিন্ডন হোয়াইট

1

কোণটি এনকোড করার আরেকটি উপায় হ'ল দুটি মানের সেট হিসাবে:

y1 = সর্বোচ্চ (0, থিতা)

y2 = সর্বোচ্চ (0, -তীত)

theta_out = y1 - y2

এই আমি সময় একটি নেটওয়ার্ক প্রশিক্ষণ এবং অন্যান্য এনকোডিং তুলনা কিন্তু হবে না যে গ্রেডিয়েন্ট থেটা = 0. এ undefined হয় arctan2 অনুরূপ সমস্যা হবে এই কাগজ কৌশল যুক্তিসঙ্গতভাবে সফল করলো।


1
এটি একটি পোস্টে অন্য প্রশ্নের সাথে মিশ্রিত উত্তর বলে মনে হচ্ছে। এই সাইটটি ফোরামে যেভাবে হয় তার থেকে কিছুটা আলাদাভাবে পরিচালনা করে। এখানে উত্তরগুলি মূল প্রশ্নের উত্তর দেওয়ার দিকে মনোনিবেশ করা উচিত। এবং আপনার যদি অন্য প্রশ্ন বা মন্তব্য থাকে - তবে এটি পোস্ট করা উচিত।
করোলিস কনসেভিয়াস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.