সরল কথায় বলা যায়, torch.Tensor.view()
যা অনুপ্রাণিত হয় numpy.ndarray.reshape()
বা numpy.reshape()
সেন্সরটির একটি নতুন দৃষ্টিভঙ্গি তৈরি করে, যতক্ষণ না নতুন আকারটি মূল টেনসরের আকারের সাথে সামঞ্জস্যপূর্ণ।
আসুন এটি একটি কংক্রিট উদাহরণ ব্যবহার করে বিস্তারিতভাবে বুঝতে পারি।
In [43]: t = torch.arange(18)
In [44]: t
Out[44]:
tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17])
t
আকারের এই টেনসর দিয়ে (18,)
, কেবলমাত্র নিম্নলিখিত আকারগুলির জন্য নতুন দর্শন তৈরি করা যেতে পারে:
(1, 18)
বা equivalently (1, -1)
বা বা equivalently বা বা equivalently বা বা equivalently বা বা equivalently বা বা equivalently বা(-1, 18)
(2, 9)
(2, -1)
(-1, 9)
(3, 6)
(3, -1)
(-1, 6)
(6, 3)
(6, -1)
(-1, 3)
(9, 2)
(9, -1)
(-1, 2)
(18, 1)
(18, -1)
(-1, 1)
যেহেতু আমরা উপরের আকারের টিউপসগুলি ইতিমধ্যে পর্যবেক্ষণ করতে পারি, শেপ টিপল (যেমন 2*9
, 3*6
ইত্যাদি) এর উপাদানগুলির গুণনটি সর্বদা মূল টেনসর ( আমাদের উদাহরণস্বরূপ) এর মোট সংখ্যার সমান হতে হবে18
।
আরেকটি বিষয় লক্ষণীয় যে আমরা -1
প্রতিটি আকারের টিপলগুলির একটিতে একটিতে একটি ব্যবহার করেছি । একটি ব্যবহার করে -1
, আমরা নিজেই গণনাটি করতে অলসতা বজায় রেখেছি এবং এটি পরিবর্তে নতুন ভিউ তৈরি করার সময় আকৃতির জন্য সেই মানটি গণনা করার জন্য টাইটটিকে পাইটর্চকে অর্পণ করব । একটি গুরুত্বপূর্ণ বিষয় লক্ষণীয় হ'ল আমরা কেবল-1
শেপ টিপলটিতে একটি একক ব্যবহার করতে পারি । অবশিষ্ট মানগুলি স্পষ্টভাবে আমাদের সরবরাহ করা উচিত। অন্য পাইটর্চ একটি নিক্ষেপ করে অভিযোগ করবে RuntimeError
:
রানটাইমআরার: কেবলমাত্র একটি মাত্রা অনুমান করা যায়
সুতরাং, উল্লিখিত সমস্ত আকারের সাথে, পাইটর্চ সর্বদা আসল টেনসরের একটি নতুন দৃশ্য ফিরে আসবে t
। এটির মূলত অর্থ হল যে এটি অনুরোধ করা প্রতিটি নতুন দর্শনের জন্য সেন্সরটির প্রসারিত তথ্যকে পরিবর্তন করে।
নীচে কয়েকটি নতুন দর্শন দিয়ে টেনারদের ধাপগুলি কীভাবে পরিবর্তন করা হয়েছে তা চিত্রিত করে ।
# stride of our original tensor `t`
In [53]: t.stride()
Out[53]: (1,)
এখন, আমরা নতুন দর্শনগুলির জন্য পদক্ষেপগুলি দেখতে পাব :
# shape (1, 18)
In [54]: t1 = t.view(1, -1)
# stride tensor `t1` with shape (1, 18)
In [55]: t1.stride()
Out[55]: (18, 1)
# shape (2, 9)
In [56]: t2 = t.view(2, -1)
# stride of tensor `t2` with shape (2, 9)
In [57]: t2.stride()
Out[57]: (9, 1)
# shape (3, 6)
In [59]: t3 = t.view(3, -1)
# stride of tensor `t3` with shape (3, 6)
In [60]: t3.stride()
Out[60]: (6, 1)
# shape (6, 3)
In [62]: t4 = t.view(6,-1)
# stride of tensor `t4` with shape (6, 3)
In [63]: t4.stride()
Out[63]: (3, 1)
# shape (9, 2)
In [65]: t5 = t.view(9, -1)
# stride of tensor `t5` with shape (9, 2)
In [66]: t5.stride()
Out[66]: (2, 1)
# shape (18, 1)
In [68]: t6 = t.view(18, -1)
# stride of tensor `t6` with shape (18, 1)
In [69]: t6.stride()
Out[69]: (1, 1)
সুতরাং যে view()
ফাংশন এর যাদু । এটি যতক্ষণ না নতুন দৃশ্যের মূল আকৃতির সাথে সামঞ্জস্যপূর্ণ হয় ততক্ষণ প্রতিটি নতুন দর্শনের জন্য (মূল) সেন্সরটির ধাপগুলি পরিবর্তন করে ।
স্ট্রেডস টিপলস থেকে অন্য একটি আকর্ষণীয় জিনিসটি আপনি পর্যবেক্ষণ করতে পারেন তা হ'ল 0 ম পজিশনে উপাদানটির মান আকৃতির টিউলের 1 ম পজিশনে উপাদানটির মানের সমান ।
In [74]: t3.shape
Out[74]: torch.Size([3, 6])
|
In [75]: t3.stride() |
Out[75]: (6, 1) |
|_____________|
এই কারণ:
In [76]: t3
Out[76]:
tensor([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17]])
অগ্রগতিতে (6, 1)
বলা হয়েছে যে 0 তম মাত্রা বরাবর একটি উপাদান থেকে পরবর্তী উপাদানটিতে যেতে , আমাদের লাফিয়ে বা 6 পদক্ষেপ নিতে হবে। (অর্থাত থেকে যেতে 0
করার 6
, এক 6 পদক্ষেপ নিতে আছে।) কিন্তু এক উপাদান থেকে 1 পরবর্তী উপাদান যেতে St মাত্রা, আমরা শুধু কেবলমাত্র একটি পদক্ষেপ (যেমন থেকে যাওয়া প্রয়োজন 2
থেকে 3
)।
সুতরাং, গণনা সম্পাদন করার জন্য কীভাবে উপাদানগুলি মেমরি থেকে অ্যাক্সেস করা হয় তার কেন্দ্রবিন্দুতে স্ট্রাইড তথ্য রয়েছে।
এই ফাংশনটি একটি দর্শন ফিরিয়ে দেবে এবং torch.Tensor.view()
যতক্ষণ না নতুন আকৃতিটি মূল টেনসরের আকারের সাথে সামঞ্জস্যপূর্ণ তার ব্যবহারের মতোই। অন্যথায়, এটি একটি অনুলিপি ফিরে আসবে।
তবে নোটগুলি torch.reshape()
সতর্ক করে যে:
সামঞ্জস্যপূর্ণ পদক্ষেপের সাথে সামঞ্জস্যপূর্ণ ইনপুট এবং ইনপুটগুলি অনুলিপি ছাড়াই পুনরায় আকার দেওয়া যেতে পারে, তবে এক অনুলিপি বনাম দেখার আচরণের উপর নির্ভর করা উচিত নয়।
reshape
পাইটর্চে এটি ডাকেনি ?!