How to calculate output of Keras UpSampling2D Layer? - image

I don't understand how the output of the Upsampling2d layer in Keras is calculated.
Let's take an example:
img_input = Input((2,2, 1))
out = UpSampling2D(size=2, interpolation="bilinear")(img_input)
model = Model(img_input, out, name='test')
input = np.array([[100, 200], [6, 8]]).reshape(1, 2, 2, 1)
model.predict(input).reshape(4, 4)
The result of this is:
array([[100. , 150. , 200. , 200. ],
[ 53. , 78.5, 104. , 104. ],
[ 6. , 7. , 8. , 8. ],
[ 6. , 7. , 8. , 8. ]], dtype=float32)
For me bilinear interpolation would get s.th. different. Let's take the 150 in the first row. For me this should be actually 100*(2/3) + 200*(1/3) = 133.33. What is different in this layer?
Thanks!

Given your input array, these are the steps to apply the bilinear upsampling of size=2:
# input array
[[100, 200],
[ 6, 8]]
# double the size and fill with existing values spreading them evenly.
# Important! the edges of the array are not filled:
[[100, _, 200, _],
[ _, _, _, _],
[ 6, _, 8, _],
[ _, _, _, _]]
# Start filling the empty spaces sequentially by applying this rule:
# Empty spaces surrounded by one or more filled values are filled with the
# arithmetic average of these values.
# We would fill the entire array in two steps:
# 1. The first step would look like this:
[[100, 150, 200, 200],
[ 53, _, 104, _],
[ 6, 7, 8, 8],
[ 6, _, 8, _]]
# 2. The second step would look like this:
[[100, 150, 200, 200],
[ 53,78.5, 104, 104],
[ 6, 7, 8, 8],
[ 6, 7, 8, 8]]
If you would rather get [100, 133, 166, 200] in the first row (and the rest of the array filled accordingly), you should produce an upsampling of size=3 and then remove the edges (res[1:5, 1:5]):
img_input = Input((2,2, 1))
out = UpSampling2D(size=3, interpolation="bilinear")(img_input)
model = Model(img_input, out, name='test')
input = np.array([[100, 200], [6, 8]]).reshape(1, 2, 2, 1)
model.predict(input).reshape(6, 6)[1:5, 1:5]
>> array([[100. , 133.33334 , 166.66667 , 200. ],
[ 68.666664 , 91.111115 , 113.55555 , 136. ],
[ 37.333324 , 48.888878 , 60.444427 , 71.999985 ],
[ 6. , 6.666667 , 7.3333335, 8. ]],
dtype=float32)

Related

How to find all possible unique paths in a grid?

I have a 3 x 3 grid with randomly placed obstacles in which there is a random starting point but no endpoint. The endpoint is created when there are no more cells to occupy. Movement can occur up, down, left or right.
How can I see all possible unique paths within the grid?
Example:
Once a cell is used when looking for a path, it cannot be used again (1 becomes a 0).
If there are no more neighbouring cells to move into the path has ended. Regardless of weather all the cells have been visited.
# bottom left is (0, 0) and top right is (2, 2)...
# start is (1, 1) and obstacle is (2, 1)
[1] [1] [1]
[1] [S] [0]
[1] [1] [1]
S = starting point
0 = obstacle
1 = open cell
With the above example there would be 6 unique paths.
path_1 = (1, 2), (2, 2) # up, right
path_2 = (1, 0), (2, 0) # down, right
path_3 = (0, 1), (0, 2), (1, 2), (2, 2) # left, up, right, right
path_4 = (0, 1), (0, 0), (1, 0), (2, 0) # left, down, right, right
path_5 = (1, 2), (0, 2), (0, 1), (0, 0), (1, 0), (2, 0) # up, left, down, down, right, right
path_6 = (1, 0), (0, 0), (0, 1), (0, 2) (1, 2), (2, 2) # down, left, up, up, right, right
To get all the paths, you can use DFS or BFS but each path needs to have a unique visited set to keep track that you:
do not go back to the same coordinate twice in a single path
allow different paths to go on the same coordinate
I wrote a DFS implementation for a grid here and the solution will rely on this example.
Solution
To do graph search one would need to define the states, which are the coordinates in this case, but for this problem we will keep track of two parameters, for convenience:
The path taken will be documented via Crack code (right=0, down=1, left=2, up=3) which is a form of chain code
the visited set for each path will de documented for the reasons noted above
The implementation in Python is as follows (in my case the top left matches coordinate (0,0) and lower right matches (n-1,n-1) for nXn grid)
import collections
def find_paths(grid, start_coord):
paths = set() # paths will be added here
state_queue = collections.deque([]) # Pending states which have not been explored yet
# State is a tuple consists of:
# 1. current coordinate
# 2. crack code path
# 3. set of visited coordinates in that path
state = [start_coord, [], {start_coord}] # Starting state
while True:
# Getting all possible neighboring states
# Crack code (right=0, down=1, left=2, up=3)
state_right = [(state[0][0],state[0][1]+1), state[1] + [0], state[2].copy()] if state[0][1]+1 < len(grid[state[0][0]]) else None
state_down = [(state[0][0]+1,state[0][1]), state[1] + [1], state[2].copy()] if state[0][0]+1 < len(grid) else None
state_left = [(state[0][0],state[0][1]-1), state[1] + [2], state[2].copy()] if state[0][1]-1 >= 0 else None
state_up = [(state[0][0]-1,state[0][1]), state[1] + [3], state[2].copy()] if state[0][0]-1 >= 0 else None
# Adding to the queue all the unvisited states, as well as to the visited to avoid returning to states
blocked_counter = 0
for next_state in [state_right, state_down, state_left, state_up]:
if next_state is None:
blocked_counter += 1
elif next_state[0] in state[2] or grid[next_state[0][0]][next_state[0][1]] == 0:
blocked_counter += 1
else:
next_state[2].add(next_state[0])
state_queue.append(next_state)
# After checking all directions' if reached a 'dead end', adding this path to the path set
if blocked_counter == 4:
paths.add(tuple(state[1]))
# Popping next state from the queue and updating the path if needed
try:
state = state_queue.pop()
except IndexError:
break
return paths
Explanation
At the beginning we create the initial state, as well as the initial path which is an empty list and the visited set, containing only the start coordinate
For each state we are in we do the following:
2.1. create the four neighboring states (advancing right, up, left or down)
2.2. checking if we can advance in each direction by checking if the path we are in already visited this coordinate and if the coordinate is valid
2.3. if we can advance in the said direction, add this next_state to the state_queue as well as to the visited set of the path
2.4. if we can not advance in any of the four directions, we reached a 'dead end' and we add the path we are in to the paths set
2.5. pop the next state from state_queue which is kind of a bad name since it is a stack (due to the appending and popping from the same side of the deque()
When the state_queue is empty, we finished the search and we can return all the found paths
When running this with the given example, i.e.
start_coord = (1,1)
grid = [[1, 1, 1],
[1, 1, 0],
[1, 1, 1]]
We get:
find_paths(grid, start_coord)
# {(2, 3, 0, 0), (3, 2, 1, 1, 0, 0), (3, 0), (2, 1, 0, 0), (1, 0), (1, 2, 3, 3, 0, 0)}
This is actually not as difficult as it seems. Since it seems to me that you are learning, I avoid giving you code and will focus on the ideas.
The solution
Since you need to find all solutions, this is a classical backtracking problem. The idea of backtracking is to try out every possibility and store all the solutions. Particularities about your problem:
grid
movement
obstacles
unique solutions
How to check everything?
You need to loop your grid and for each point and for each point, starting from a depth of 0, you repeat the following:
if depth < available points map the possible moves (no obstacles, not visited) (1)
for each point:
increase depth with 1
mark the current point as visited
check whether there was a solution and handle it if so
with the current status, jump to (1)
unmark the current point from being visited
decrease depth by 1
Handling the solution
You need to have a unique, predictable signature for your solution, like the points you have moved to in their order and store all solutions you had so far. Before you enter your new solution, check whether it's already among the solutions and only append it if it's not there.
Pruning
You can prune your findings based on earlier findings, if the problem-space is big-enough to make this a performance optimization, but you should only consider that when you already have a solution.
I was looking to solve this with dynamic programming to avoid the exponential time complexity but failed to do so. However, here is a dense version in Javascript which uses DFS (which given this problem is the same as brute-forcing since we are interested in all possible paths) and recursion in a functional style with es6 features. We also make use of a single-dimension array to represent the board with the directions method accounting for which positions are reachable from a given position. The single-dimension array contains the rows of the board laid out sequentially from top to bottom.
[ 0 1 2 ]
[ 3 4 5 ] => [0, 1, 2, 3, 4, 5, 6, 7, 8]
[ 6 7 8 ]
The algorithm works for any m by n grid and so we must specify the width as an input parameter.
const directions = (pos, board, width) => {
const [n, s, w, e] = [pos - width, pos + width, pos - 1, pos + 1]
return [
n >= 0 && board[n] ? n : null,
s < board.length && board[s] ? s : null,
pos % width !== 0 && board[w] ? w : null,
e % width !== 0 && board[e] ? e : null
]
.filter(pos => pos !== null)
}
const solve = (pos, board, width, path) => {
const next = directions(pos, board, width)
return next.length === 0 ?
[[...path, pos]] // have a complete path
:
next
.map(nextPos => solve(nextPos, [...board.slice(0, pos), 0, ...board.slice(pos + 1)], width, [...path, pos]))
.flat()
}
const oneDim2TwoDim = (oneDimCoord, width) =>
[Math.floor(oneDimCoord / width), oneDimCoord % width]
const res = solve(4, [1, 1, 1, 1, 1, 0, 1, 1, 1], 3, [])
console.log(res.map(path => path.map(step => oneDim2TwoDim(step, 3))))
At each step, we check which directions are possible to go in. If no direction is available, we return the current path, otherwise we make a recursive call in each of the directions.
Use it like
solve(4, [1, 1, 1, 1, 1, 0, 1, 1, 1], 3, [])
/*
[
[ 4, 1, 0, 3, 6, 7, 8],
[ 4, 1, 2 ],
[ 4, 7, 6, 3, 0, 1, 2],
[ 4, 7, 8 ],
[ 4, 3, 0, 1, 2 ],
[ 4, 3, 6, 7, 8 ]
]
*/
Each path starts with the starting position and you can easily convert it back to (x, y) coordinate style with
const oneDim2TwoDim = (oneDimCoord, width) =>
[Math.floor(oneDimCoord / width), oneDimCoord % width]
const res = solve(4, [1, 1, 1, 1, 1, 0, 1, 1, 1], 3, [])
.map(path => path.map(step => oneDim2TwoDim(step, 3)))
/*
[
[ [ 1, 1 ], [ 0, 1 ], [ 0, 0 ], [ 1, 0 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ] ],
[ [ 1, 1 ], [ 0, 1 ], [ 0, 2 ] ],
[ [ 1, 1 ], [ 2, 1 ], [ 2, 0 ], [ 1, 0 ], [ 0, 0 ], [ 0, 1 ], [ 0, 2 ] ],
[ [ 1, 1 ], [ 2, 1 ], [ 2, 2 ] ],
[ [ 1, 1 ], [ 1, 0 ], [ 0, 0 ], [ 0, 1 ], [ 0, 2 ] ],
[ [ 1, 1 ], [ 1, 0 ], [ 2, 0 ], [ 2, 1 ], [ 2, 2 ] ]
]
*/

how do i reverse individual (and specific) columns in a 2d array (RUBY)

RUBY the goal is to get the max value from each of the four zones and get their sum.
UPDATE I came up with a solution, I'm sorry about the mixup. It turned out that the matrix is a 2n x 2n matrix so it could have been greater or smaller than 4x4 in fact it. The solution i wrote below worked on all of the test cases. Here is a link to the problem
I tried doing matrix.transpose then I tried reversing the specific array, that didn't work for all edge cases.
Here is the code for that
def flippingMatrix(matrix)
2.times do
matrix = matrix.transpose
matrix = matrix.map do |array|
if (array[-1] == array.max) || (array[-2] == array.max)
array.reverse
else
array
end
end
end
return matrix[0][0] + matrix[0][1] + matrix[1][0] + matrix[1][1]
end
I gave up and tried the below, which in my mind works, it also works for most edge cases but not all.
But i'm getting an error (undefined method `[]' for nil:NilClass (NoMethodError))
keep in mind when I print the results or spot_1, spot_2, spot_3, or spot_4 I get the correct answer. does anyone have an idea why this is happening?
Here is a matrix that FAILED
[
[517, 37, 380, 3727],
[3049, 1181, 2690, 1587],
[3227, 3500, 2665, 383],
[4041, 2013, 384, 965]
]
**expected output: 12,881 (this fails)**
**because 4041 + 2013 + 3227 + 3500 = 12,881**
Here is a matrix that PASSED
[
[112, 42, 83, 119],
[56, 125, 56, 49],
[15, 78, 101, 43],
[62, 98, 114, 108],
]
**expected output: 414 (this passes)**
Here is the code
def flippingMatrix(matrix)
# Write your code here
spot_1 = [matrix[0][0] , matrix[0][3] , matrix[3][0] , matrix[3][3]].max
spot_2 = [matrix[0][1] , matrix[0][2] , matrix[3][1] , matrix[3][2]].max
spot_3 = [matrix[1][0] , matrix[1][3] , matrix[2][0] , matrix[2][3]].max
spot_4 = [matrix[1][1] , matrix[1][2] , matrix[2][1] , matrix[2][2]].max
return (spot_1 + spot_2 + spot_3 + spot_4)
end
I will answer your question and at the same time suggest two other ways to obtain the desired sum.
Suppose
arr = [
[ 1, 30, 40, 2],
[300, 4000, 1000, 200],
[400, 3000, 2000, 100],
[ 4, 10, 20, 3]
]
First solution
We see that the desired return value is 4444. This corresponds to
A B B A
C D D C
C D D C
A B B A
First create three helper methods.
Compute the largest value among the four inner elements
def mx(arr)
[arr[1][1], arr[1][2], arr[2][1], arr[2][2]].max
end
mx(arr)
#=> 4000
This is the largest of the "D" values.
Reverse the first two and last two rows
def row_flip(arr)
[arr[1], arr[0], arr[3], arr[2]]
end
row_flip(arr)
#=> [[300, 4000, 1000, 200],
# [ 1, 30, 40, 2],
# [ 4, 10, 20, 3],
# [400, 3000, 2000, 100]]
This allows us to use the method mx to obtain the largest of the "B" values.
Reverse the first two and last two columns
def column_flip(arr)
row_flip(arr.transpose).transpose
end
column_flip(arr)
#= [[ 30, 1, 2, 40],
# [4000, 300, 200, 1000],
# [3000, 400, 100, 2000],
# [ 10, 4, 3, 20]]
This allows us to use the method mx to obtain the largest of the "C" values.
Lastly, the maximum of the "A" values can be computed as follows.
t = row_flip(column_flip(arr))
#=> [[4000, 300, 200, 1000],
# [ 30, 1, 2, 40],
# [ 10, 4, 3, 20],
# [3000, 400, 100, 2000]]
mx(column_flip(t))
#=> 4
The sum of the maximum values may therefore be computed as follows.
def sum_max(arr)
t = column_flip(arr)
mx(arr) + mx(row_flip(arr)) + mx(t) + mx(row_flip(t))
end
sum_max(arr)
#=> 4444
Second solution
Another way is the following:
[0, 1].product([0, 1]).sum do |i, j|
[arr[i][j], arr[i][-j-1], arr[-i-1][j], arr[-i-1][-j-1]].max
end
#=> 4444
To see how this works let me break this into two statements add a puts statement. Note that, for each of the groups A, B, C and D, the block variables i and j are the row and column indices of the top-left element of the group.
top_left_indices = [0, 1].product([0, 1])
#=> [[0, 0], [0, 1], [1, 0], [1, 1]]
top_left_indices.sum do |i, j|
a = [arr[i][j], arr[i][-j-1], arr[-i-1][j], arr[-i-1][-j-1]]
puts a
a.max
end
#=> 4444
The prints the following.
[1, 2, 4, 3]
[30, 40, 10, 20]
[300, 200, 400, 100]
[4000, 1000, 3000, 2000]
ahhh I came up with an answer that answers all edge cases. I originally saw something like this in Javascript and kind of turned it into Ruby. Apparently some of the hidden edge cases (that were hidden) weren't all 4 by 4 some were smaller and some larger, that was the cause of the nil error.
Here is the solution:
def flippingMatrix(matrix)
total = []
(0...(matrix.length/2)).each do |idx1|
(0...(matrix.length/2)).each do |idx2|
total << [matrix[idx1][idx2],
matrix[(matrix.length - 1)-idx1][idx2],
matrix[idx1][(matrix.length - 1)-idx2],
matrix[(matrix.length - 1)-idx1][(matrix.length - 1)-idx2]].max
end
end
total.sum
end
Thank you all for your support! I hope this helps someone in the near future.

OpenSCAD how to access a value within a Matrix

How do I index a matrix in OpenSCAD or iterate through it in a loop?
I'm trying to either access and assign the values assigned to coordinates through the forloop to their single variables as below, or at least be able to access the values separately in the Matrix.
for ( coordinates = [ [ 15, 15, 2],
[ 15, -15, 2],
[ -15, -15, 2],
[ -15, 15, 2] ])
{
x = coordinates[0];
y = coordinates[1];
z = coordinates[2];
translate([x+4, y, z]){
cube([x,y,z]);
}
}
First off, standard variables are set at compile-time in OpenSCAD, not run-time (official documentation stating that), so you can't assign values to them in a loop. You'll have to inline references to coordinates to use the values in it.
The second issue is that you can't make a cube with a negative size, or so I'm guessing from the fact that I get no output from the second through fourth iterations of the loop as provided. You can wrap the values passed into cube in abs() calls to get the absolute value to ensure it's positive.
Here's a working sample of inlining the coordinates variable and using abs() to pass positive values to cube():
for ( coordinates = [ [ 15, 15, 2],
[ 15, -15, 2],
[ -15, -15, 2],
[ -15, 15, 2] ])
{
translate([coordinates[0] + 4, coordinates[1], coordinates[2]]) {
cube([abs(coordinates[0]), abs(coordinates[1]), abs(coordinates[2])]);
}
}

Ruby exclude value in range

I want to build an array using range (0..x) while excluding certain ranges and values.
Example:
array = [1, 2, 3, .., 50, 60, .., 98, 100]
How is this done?
Your example is:
array = [1, 2, 3,..., 50, 60,..., 98, 100]
If this means array is to contain the numbers 1 through 50, 60 through 98 and 100, then you can write that:
array = [*1..50, *60..98, 100]
#=> [1, 2, 3,...49, 50, 60, 61, 62,...98, 100]
Subtracting one range from another:
(1..100).to_a - (51...60).to_a
To remove additional specific values, create an array of those values and subtract them too:
(1..100).to_a - (51...60).to_a - [82, 56, 23]
To add some cleanliness:
values_to_remove = [(51..60), [34,67,98]].flat_map(&:to_a)
(1..100).to_a - values_to_remove
I want to build an array using range (0..x) while excluding certain
ranges and values.
As per ruby-docs, you can excluded a range using Enumerable#grep_v:
(1..10).grep_v(2..4) #=> [1, 5, 6, 7, 8, 9, 10]
grep_v only defines one parameter so to exclude more than one range you would have to do something like:
(1..10).grep_v(2..4).grep_v(6..8) #=> [1, 5, 9, 10]
Values can be used as the argument if a range is not required e.g. grep_v(1).
Since Rails 6, you can build the example array in question using ranges + excluding:
(1..100).excluding(*(51..59), 100)

Finding continuous number sequence

How to find the longest continuous number sequence in array of number arrays? Each array of numbers represent one or zero numbers in resulting sequence.
Example ([] - represents array (like in javascript)):
[
[1, 5, 6],
[7],
[22, 34],
[500, 550],
[60, 1],
[90, 100],
[243],
[250, 110],
[150],
[155],
[160]
]
Correct output would be: [1, 7, 22, 60, 90, 110, 150, 155, 160]
Detailed output:
1, -- index 1 all 1, 5 and 6 would match here, pick the smallest
7, -- index 2
22, -- index 3
-- index 4 skipped, the sequence would end here or wouldn't be the longest possible
60, -- index 5 picked 60, because 1 wouldn't continue in the sequence
90, -- index 6
-- index 7 skipped, the sequence would end here or wouldn't be the longest possible
110, -- index 8
150, -- index 9
155, -- index 10
160 -- index 11
A possible approach is to use dynamic programming using as parameters the last value and the index of first sub-array to consider.
This is a solution in Python based on recursion with memoization
data = [[1, 5, 6],
[7],
[22, 34],
[500, 550],
[60, 1],
[90, 100],
[243],
[250, 110],
[150],
[155],
[160]]
def longest(x0, i, _cache=dict()):
if i == len(data):
return []
try:
return _cache[x0, i]
except KeyError:
best = longest(x0, i+1)
for x in data[i]:
if x >= x0:
L = [x] + longest(x, i+1)
if len(L) > len(best):
best = L
_cache[x0, i] = best
return best
print longest(0, 0)

Resources